Skip to content

Commit 637cec9

Browse files
Query document reference by object with id
works :)
1 parent f186dc4 commit 637cec9

File tree

5 files changed

+92
-4
lines changed

5 files changed

+92
-4
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,35 @@ public DBRef toDBRef(Object object, @Nullable MongoPersistentProperty referringP
577577
return createDBRef(object, referringProperty);
578578
}
579579

580+
public Object toDocumentReference(Object source, @Nullable MongoPersistentProperty referringProperty) {
581+
582+
if (source instanceof LazyLoadingProxy) {
583+
return ((LazyLoadingProxy) source).getSource();
584+
}
585+
586+
if (referringProperty != null) {
587+
588+
if (referringProperty.isDbReference()) {
589+
return toDBRef(source, referringProperty);
590+
}
591+
if (referringProperty.isDocumentReference()) {
592+
return createDocumentPointer(source, referringProperty);
593+
}
594+
}
595+
596+
throw new RuntimeException("oops - what's that " + source);
597+
}
598+
599+
Object createDocumentPointer(Object source, @Nullable MongoPersistentProperty referringProperty) {
600+
601+
if (conversionService.canConvert(referringProperty.getType(), DocumentPointer.class)) {
602+
return conversionService.convert(source, DocumentPointer.class).getPointer();
603+
}
604+
605+
return mappingContext.getPersistentEntity(referringProperty.getAssociationTargetType())
606+
.getIdentifierAccessor(source).getIdentifier();
607+
}
608+
580609
/**
581610
* Root entry method into write conversion. Adds a type discriminator to the {@link Document}. Shouldn't be called for
582611
* nested conversions.

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoWriter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,8 @@ default Object convertToMongoType(@Nullable Object obj, MongoPersistentEntity<?>
7070
* @return will never be {@literal null}.
7171
*/
7272
DBRef toDBRef(Object object, @Nullable MongoPersistentProperty referingProperty);
73+
74+
default Object toDocumentReference(Object source, @Nullable MongoPersistentProperty referringProperty) {
75+
return toDBRef(source, referringProperty);
76+
}
7377
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers
605605
if (source instanceof Iterable) {
606606
BasicDBList result = new BasicDBList();
607607
for (Object element : (Iterable<?>) source) {
608-
result.add(createDbRefFor(element, property));
608+
result.add(createReferenceFor(element, property));
609609
}
610610
return result;
611611
}
@@ -614,12 +614,12 @@ protected Object convertAssociation(@Nullable Object source, @Nullable MongoPers
614614
Document result = new Document();
615615
Document dbObject = (Document) source;
616616
for (String key : dbObject.keySet()) {
617-
result.put(key, createDbRefFor(dbObject.get(key), property));
617+
result.put(key, createReferenceFor(dbObject.get(key), property));
618618
}
619619
return result;
620620
}
621621

622-
return createDbRefFor(source, property);
622+
return createReferenceFor(source, property);
623623
}
624624

625625
/**
@@ -666,12 +666,16 @@ private Entry<String, Object> createMapEntry(String key, @Nullable Object value)
666666
return Collections.singletonMap(key, value).entrySet().iterator().next();
667667
}
668668

669-
private DBRef createDbRefFor(Object source, MongoPersistentProperty property) {
669+
private Object createReferenceFor(Object source, MongoPersistentProperty property) {
670670

671671
if (source instanceof DBRef) {
672672
return (DBRef) source;
673673
}
674674

675+
if(property != null && property.isDocumentReference()) {
676+
return converter.toDocumentReference(source, property);
677+
}
678+
675679
return converter.toDBRef(source, property);
676680
}
677681

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,28 @@ void loadCollectionReferenceWithMissingRefs() {
584584
assertThat(result.getSimpleValueRef()).containsExactly(new SimpleObjectRef("ref-2", "me-the-2-referenced-object"));
585585
}
586586

587+
@Test // GH-3602
588+
void queryForReference() {
589+
590+
String collectionB = template.getCollectionName(WithRefB.class);
591+
592+
WithRefB b = new WithRefB();
593+
b.id = "b";
594+
template.save(b);
595+
596+
WithRefA a = new WithRefA();
597+
a.id = "a";
598+
a.toB = b;
599+
template.save(a);
600+
601+
WithRefA a2 = new WithRefA();
602+
a2.id = "a2";
603+
template.save(a2);
604+
605+
WithRefA loadedA = template.query(WithRefA.class).matching(where("toB").is(b)).firstValue();
606+
assertThat(loadedA.getId()).isEqualTo(a.getId());
607+
}
608+
587609
@Data
588610
static class SingleRefRoot {
589611

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
4949
import org.springframework.data.mongodb.core.mapping.DBRef;
5050
import org.springframework.data.mongodb.core.mapping.Document;
51+
import org.springframework.data.mongodb.core.mapping.DocumentReference;
5152
import org.springframework.data.mongodb.core.mapping.Field;
5253
import org.springframework.data.mongodb.core.mapping.FieldType;
5354
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
@@ -1487,4 +1488,32 @@ static class WithPropertyUsingUnderscoreInName {
14871488
@Field("renamed")
14881489
String renamed_fieldname_with_underscores;
14891490
}
1491+
1492+
static class WithDocumentReferences {
1493+
1494+
@DocumentReference
1495+
Sample sample;
1496+
1497+
@DocumentReference
1498+
SimpeEntityWithoutId noId;
1499+
1500+
@DocumentReference(lookup = "{ 'stringProperty' : ?#{stringProperty} }")
1501+
SimpeEntityWithoutId noIdButLookupQuery;
1502+
1503+
}
1504+
1505+
@Test
1506+
void xxx() {
1507+
1508+
Sample sample = new Sample();
1509+
sample.foo = "sample-id";
1510+
1511+
Query query = query(where("sample").is(sample));
1512+
1513+
org.bson.Document mappedObject = mapper.getMappedObject(query.getQueryObject(),
1514+
context.getPersistentEntity(WithDocumentReferences.class));
1515+
1516+
System.out.println("mappedObject.toJson(): " + mappedObject.toJson());
1517+
}
1518+
14901519
}

0 commit comments

Comments
 (0)