Skip to content

Commit 501b950

Browse files
christophstroblodrotbohm
authored andcommitted
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: spring-projects#333.
1 parent 727271e commit 501b950

File tree

3 files changed

+172
-8
lines changed

3 files changed

+172
-8
lines changed

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

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011 by the original author(s).
2+
* Copyright (c) 2011-2015 by the original author(s).
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717

1818
import java.io.Serializable;
1919

20+
import org.bson.types.ObjectId;
2021
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
2122
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
2223
import org.springframework.data.repository.core.support.PersistentEntityInformation;
@@ -27,20 +28,26 @@
2728
* {@link MongoPersistentEntity} if given.
2829
*
2930
* @author Oliver Gierke
31+
* @author Christoph Strobl
3032
*/
3133
public class MappingMongoEntityInformation<T, ID extends Serializable> extends PersistentEntityInformation<T, ID>
3234
implements MongoEntityInformation<T, ID> {
3335

3436
private final MongoPersistentEntity<T> entityMetadata;
3537
private final String customCollectionName;
38+
private final Class<ID> fallbackIdType;
3639

3740
/**
3841
* Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity}.
3942
*
4043
* @param entity must not be {@literal null}.
4144
*/
4245
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity) {
43-
this(entity, null);
46+
this(entity, null, null);
47+
}
48+
49+
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity, Class<ID> fallbackIdType) {
50+
this(entity, (String) null, fallbackIdType);
4451
}
4552

4653
/**
@@ -51,11 +58,16 @@ public MappingMongoEntityInformation(MongoPersistentEntity<T> entity) {
5158
* @param customCollectionName can be {@literal null}.
5259
*/
5360
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity, String customCollectionName) {
61+
this(entity, customCollectionName, null);
62+
}
63+
64+
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity, String customCollectionName, Class<ID> idType) {
5465

5566
super(entity);
5667

5768
this.entityMetadata = entity;
5869
this.customCollectionName = customCollectionName;
70+
this.fallbackIdType = idType != null ? idType : (Class<ID>) ObjectId.class;
5971
}
6072

6173
/* (non-Javadoc)
@@ -71,4 +83,19 @@ public String getCollectionName() {
7183
public String getIdAttribute() {
7284
return entityMetadata.getIdProperty().getName();
7385
}
86+
87+
/*
88+
* (non-Javadoc)
89+
* @see org.springframework.data.repository.core.support.PersistentEntityInformation#getIdType()
90+
*/
91+
@Override
92+
@SuppressWarnings("unchecked")
93+
public Class<ID> getIdType() {
94+
95+
if (this.entityMetadata.hasIdProperty()) {
96+
return super.getIdType();
97+
}
98+
99+
return fallbackIdType != null ? fallbackIdType : (Class<ID>) ObjectId.class;
100+
}
74101
}

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

+15-6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
*
4949
* @author Oliver Gierke
5050
* @author Thomas Darimont
51+
* @author Christoph Strobl
5152
*/
5253
public class MongoRepositoryFactory extends RepositoryFactorySupport {
5354

@@ -89,7 +90,8 @@ protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
8990
@Override
9091
protected Object getTargetRepository(RepositoryInformation information) {
9192

92-
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType());
93+
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType(),
94+
information);
9395
return getTargetRepositoryViaReflection(information, entityInformation, mongoOperations);
9496
}
9597

@@ -106,18 +108,25 @@ protected QueryLookupStrategy getQueryLookupStrategy(Key key, EvaluationContextP
106108
* (non-Javadoc)
107109
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class)
108110
*/
109-
@Override
110-
@SuppressWarnings("unchecked")
111+
// TODO: would be worth discussing if we could alter RepositoryFactorySupport#getEntityInformation to be called with
112+
// RepositoryMetadata instead of the acual domain type class.
111113
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
114+
return getEntityInformation(domainClass, null);
115+
}
116+
117+
@SuppressWarnings("unchecked")
118+
private <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass,
119+
RepositoryInformation information) {
112120

113121
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
114122

115123
if (entity == null) {
116-
throw new MappingException(
117-
String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName()));
124+
throw new MappingException(String.format("Could not lookup mapping metadata for domain class %s!",
125+
domainClass.getName()));
118126
}
119127

120-
return new MappingMongoEntityInformation<T, ID>((MongoPersistentEntity<T>) entity);
128+
return new MappingMongoEntityInformation<T, ID>((MongoPersistentEntity<T>) entity,
129+
information != null ? (Class<ID>) information.getIdType() : null);
121130
}
122131

123132
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mongodb.core;
17+
18+
import static org.hamcrest.core.Is.*;
19+
import static org.junit.Assert.*;
20+
import static org.springframework.data.mongodb.core.query.Criteria.*;
21+
import static org.springframework.data.mongodb.core.query.Query.*;
22+
23+
import java.util.Map;
24+
25+
import org.junit.Before;
26+
import org.junit.Test;
27+
import org.junit.runner.RunWith;
28+
import org.springframework.beans.factory.annotation.Autowired;
29+
import org.springframework.context.annotation.Configuration;
30+
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
31+
import org.springframework.data.mongodb.repository.MongoRepository;
32+
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
33+
import org.springframework.test.context.ContextConfiguration;
34+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
35+
36+
import com.mongodb.Mongo;
37+
import com.mongodb.MongoClient;
38+
39+
/**
40+
* @author Christoph Strobl
41+
*/
42+
@RunWith(SpringJUnit4ClassRunner.class)
43+
@ContextConfiguration
44+
public class NoExplicitIdTests {
45+
46+
@Configuration
47+
@EnableMongoRepositories(considerNestedRepositories = true)
48+
static class Config extends AbstractMongoConfiguration {
49+
50+
@Override
51+
protected String getDatabaseName() {
52+
return "test";
53+
}
54+
55+
@Override
56+
public Mongo mongo() throws Exception {
57+
return new MongoClient();
58+
}
59+
}
60+
61+
@Autowired MongoOperations mongoOps;
62+
@Autowired TypeWithoutExplicitIdPropertyRepository repo;
63+
64+
@Before
65+
public void setUp() {
66+
mongoOps.dropCollection(TypeWithoutIdProperty.class);
67+
}
68+
69+
/**
70+
* @see DATAMONGO-1289
71+
*/
72+
@Test
73+
public void saveAndRetrieveTypeWithoutIdPorpertyViaTemplate() {
74+
75+
TypeWithoutIdProperty noid = new TypeWithoutIdProperty();
76+
noid.someString = "o.O";
77+
78+
mongoOps.save(noid);
79+
80+
TypeWithoutIdProperty retrieved = mongoOps.findOne(query(where("someString").is(noid.someString)),
81+
TypeWithoutIdProperty.class);
82+
83+
assertThat(retrieved.someString, is(noid.someString));
84+
}
85+
86+
/**
87+
* @see DATAMONGO-1289
88+
*/
89+
@Test
90+
public void saveAndRetrieveTypeWithoutIdPorpertyViaRepository() {
91+
92+
TypeWithoutIdProperty noid = new TypeWithoutIdProperty();
93+
noid.someString = "o.O";
94+
95+
repo.save(noid);
96+
97+
TypeWithoutIdProperty retrieved = repo.findBySomeString(noid.someString);
98+
assertThat(retrieved.someString, is(noid.someString));
99+
}
100+
101+
/**
102+
* @see DATAMONGO-1289
103+
*/
104+
@Test
105+
public void saveAndRetrieveTypeWithoutIdPorpertyViaRepositoryFindOne() {
106+
107+
TypeWithoutIdProperty noid = new TypeWithoutIdProperty();
108+
noid.someString = "o.O";
109+
110+
repo.save(noid);
111+
112+
Map<String, Object> map = mongoOps.findOne(query(where("someString").is(noid.someString)), Map.class,
113+
"typeWithoutIdProperty");
114+
115+
TypeWithoutIdProperty retrieved = repo.findOne(map.get("_id").toString());
116+
assertThat(retrieved.someString, is(noid.someString));
117+
}
118+
119+
static class TypeWithoutIdProperty {
120+
121+
String someString;
122+
}
123+
124+
static interface TypeWithoutExplicitIdPropertyRepository extends MongoRepository<TypeWithoutIdProperty, String> {
125+
126+
TypeWithoutIdProperty findBySomeString(String someString);
127+
}
128+
}

0 commit comments

Comments
 (0)