Browse Source

DATAMONGO-1289 - MappingMongoEntityInformation no uses fallback identifier type derived from repository declaration.

We now use RepositoryMetdata.getIdType() to provide a fallback identifier type in case the entity information does not hold an id property which is perfectly valid for MongoDB.

Original pull request: #333.
pull/337/merge
Christoph Strobl 10 years ago committed by Oliver Gierke
parent
commit
501b9501e0
  1. 31
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java
  2. 21
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactory.java
  3. 128
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/NoExplicitIdTests.java

31
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 by the original author(s).
* Copyright (c) 2011-2015 by the original author(s).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@ package org.springframework.data.mongodb.repository.support; @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.repository.support;
import java.io.Serializable;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.repository.core.support.PersistentEntityInformation;
@ -27,12 +28,14 @@ import org.springframework.data.repository.core.support.PersistentEntityInformat @@ -27,12 +28,14 @@ import org.springframework.data.repository.core.support.PersistentEntityInformat
* {@link MongoPersistentEntity} if given.
*
* @author Oliver Gierke
* @author Christoph Strobl
*/
public class MappingMongoEntityInformation<T, ID extends Serializable> extends PersistentEntityInformation<T, ID>
implements MongoEntityInformation<T, ID> {
private final MongoPersistentEntity<T> entityMetadata;
private final String customCollectionName;
private final Class<ID> fallbackIdType;
/**
* Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity}.
@ -40,7 +43,11 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P @@ -40,7 +43,11 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P
* @param entity must not be {@literal null}.
*/
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity) {
this(entity, null);
this(entity, null, null);
}
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity, Class<ID> fallbackIdType) {
this(entity, (String) null, fallbackIdType);
}
/**
@ -51,11 +58,16 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P @@ -51,11 +58,16 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P
* @param customCollectionName can be {@literal null}.
*/
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity, String customCollectionName) {
this(entity, customCollectionName, null);
}
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity, String customCollectionName, Class<ID> idType) {
super(entity);
this.entityMetadata = entity;
this.customCollectionName = customCollectionName;
this.fallbackIdType = idType != null ? idType : (Class<ID>) ObjectId.class;
}
/* (non-Javadoc)
@ -71,4 +83,19 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P @@ -71,4 +83,19 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P
public String getIdAttribute() {
return entityMetadata.getIdProperty().getName();
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.support.PersistentEntityInformation#getIdType()
*/
@Override
@SuppressWarnings("unchecked")
public Class<ID> getIdType() {
if (this.entityMetadata.hasIdProperty()) {
return super.getIdType();
}
return fallbackIdType != null ? fallbackIdType : (Class<ID>) ObjectId.class;
}
}

21
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactory.java

@ -48,6 +48,7 @@ import org.springframework.util.Assert; @@ -48,6 +48,7 @@ import org.springframework.util.Assert;
*
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
*/
public class MongoRepositoryFactory extends RepositoryFactorySupport {
@ -89,7 +90,8 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport { @@ -89,7 +90,8 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
@Override
protected Object getTargetRepository(RepositoryInformation information) {
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType());
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType(),
information);
return getTargetRepositoryViaReflection(information, entityInformation, mongoOperations);
}
@ -106,18 +108,25 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport { @@ -106,18 +108,25 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
* (non-Javadoc)
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class)
*/
@Override
@SuppressWarnings("unchecked")
// TODO: would be worth discussing if we could alter RepositoryFactorySupport#getEntityInformation to be called with
// RepositoryMetadata instead of the acual domain type class.
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
return getEntityInformation(domainClass, null);
}
@SuppressWarnings("unchecked")
private <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass,
RepositoryInformation information) {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
if (entity == null) {
throw new MappingException(
String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName()));
throw new MappingException(String.format("Could not lookup mapping metadata for domain class %s!",
domainClass.getName()));
}
return new MappingMongoEntityInformation<T, ID>((MongoPersistentEntity<T>) entity);
return new MappingMongoEntityInformation<T, ID>((MongoPersistentEntity<T>) entity,
information != null ? (Class<ID>) information.getIdType() : null);
}
/**

128
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/NoExplicitIdTests.java

@ -0,0 +1,128 @@ @@ -0,0 +1,128 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.core;
import static org.hamcrest.core.Is.*;
import static org.junit.Assert.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
/**
* @author Christoph Strobl
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class NoExplicitIdTests {
@Configuration
@EnableMongoRepositories(considerNestedRepositories = true)
static class Config extends AbstractMongoConfiguration {
@Override
protected String getDatabaseName() {
return "test";
}
@Override
public Mongo mongo() throws Exception {
return new MongoClient();
}
}
@Autowired MongoOperations mongoOps;
@Autowired TypeWithoutExplicitIdPropertyRepository repo;
@Before
public void setUp() {
mongoOps.dropCollection(TypeWithoutIdProperty.class);
}
/**
* @see DATAMONGO-1289
*/
@Test
public void saveAndRetrieveTypeWithoutIdPorpertyViaTemplate() {
TypeWithoutIdProperty noid = new TypeWithoutIdProperty();
noid.someString = "o.O";
mongoOps.save(noid);
TypeWithoutIdProperty retrieved = mongoOps.findOne(query(where("someString").is(noid.someString)),
TypeWithoutIdProperty.class);
assertThat(retrieved.someString, is(noid.someString));
}
/**
* @see DATAMONGO-1289
*/
@Test
public void saveAndRetrieveTypeWithoutIdPorpertyViaRepository() {
TypeWithoutIdProperty noid = new TypeWithoutIdProperty();
noid.someString = "o.O";
repo.save(noid);
TypeWithoutIdProperty retrieved = repo.findBySomeString(noid.someString);
assertThat(retrieved.someString, is(noid.someString));
}
/**
* @see DATAMONGO-1289
*/
@Test
public void saveAndRetrieveTypeWithoutIdPorpertyViaRepositoryFindOne() {
TypeWithoutIdProperty noid = new TypeWithoutIdProperty();
noid.someString = "o.O";
repo.save(noid);
Map<String, Object> map = mongoOps.findOne(query(where("someString").is(noid.someString)), Map.class,
"typeWithoutIdProperty");
TypeWithoutIdProperty retrieved = repo.findOne(map.get("_id").toString());
assertThat(retrieved.someString, is(noid.someString));
}
static class TypeWithoutIdProperty {
String someString;
}
static interface TypeWithoutExplicitIdPropertyRepository extends MongoRepository<TypeWithoutIdProperty, String> {
TypeWithoutIdProperty findBySomeString(String someString);
}
}
Loading…
Cancel
Save