Skip to content

Commit 8d70d8c

Browse files
authored
Merge pull request #42 from kaiso/feature/#40
Feature/#40
2 parents d884dc4 + c35dbee commit 8d70d8c

File tree

8 files changed

+221
-66
lines changed

8 files changed

+221
-66
lines changed

pom.xml

+6-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>io.github.kaiso.relmongo</groupId>
77
<artifactId>relmongo</artifactId>
8-
<version>3.0.0</version>
8+
<version>3.0.1</version>
99
<packaging>jar</packaging>
1010

1111
<name>relmongo</name>
@@ -18,11 +18,11 @@
1818
<maven.compiler.target>1.8</maven.compiler.target>
1919
<maven.plugin.source.version>3.0.1</maven.plugin.source.version>
2020
<maven.plugin.javadoc.version>3.0.1</maven.plugin.javadoc.version>
21-
<spring.data.version>2.1.3.RELEASE</spring.data.version>
22-
<spring.version>5.1.3.RELEASE</spring.version>
21+
<spring.data.version>2.1.8.RELEASE</spring.data.version>
22+
<spring.version>5.1.7.RELEASE</spring.version>
2323
<mongo.driver.version>3.9.1</mongo.driver.version>
24-
<junit.jupiter.version>5.2.0</junit.jupiter.version>
25-
<junit.platform.version>1.2.0</junit.platform.version>
24+
<junit.jupiter.version>5.4.1</junit.jupiter.version>
25+
<junit.platform.version>1.4.2</junit.platform.version>
2626
</properties>
2727

2828

@@ -161,14 +161,7 @@
161161
</plugin>
162162
<plugin>
163163
<artifactId>maven-surefire-plugin</artifactId>
164-
<version>2.21.0</version>
165-
<dependencies>
166-
<dependency>
167-
<groupId>org.junit.platform</groupId>
168-
<artifactId>junit-platform-surefire-provider</artifactId>
169-
<version>${junit.platform.version}</version>
170-
</dependency>
171-
</dependencies>
164+
<version>2.22.0</version>
172165
</plugin>
173166
<plugin>
174167
<groupId>org.sonatype.plugins</groupId>

src/main/java/io/github/kaiso/relmongo/events/callback/PersistentPropertyCascadingRemoveCallback.java

+26-17
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.lang.reflect.Field;
3131
import java.util.Arrays;
3232
import java.util.Collection;
33+
3334
/**
3435
*
3536
* @author Kais OMRI
@@ -39,18 +40,14 @@ public class PersistentPropertyCascadingRemoveCallback implements FieldCallback
3940

4041
private Document source;
4142
private MongoOperations mongoOperations;
42-
private ObjectId id;
43+
private Boolean loaded = Boolean.FALSE;
4344
private Object entity;
4445

4546
public PersistentPropertyCascadingRemoveCallback(Document source, MongoOperations mongoOperations, Class<?> clazz) {
4647
super();
4748
this.source = source;
4849
this.mongoOperations = mongoOperations;
49-
this.id = this.source.getObjectId("_id");
50-
if (this.id != null) {
51-
Collection<?> findByIds = DatabaseOperations.findByIds(mongoOperations, clazz, id);
52-
this.entity = findByIds != null && !findByIds.isEmpty() ? findByIds.iterator().next() : null;
53-
}
50+
this.entity = mongoOperations.getConverter().read(clazz, source);
5451
}
5552

5653
public void doWith(Field field) throws IllegalAccessException {
@@ -64,36 +61,48 @@ public void doWith(Field field) throws IllegalAccessException {
6461
}
6562

6663
private void doCascade(Field field, CascadeType cascadeType) throws IllegalAccessException {
64+
if (!Arrays.asList(CascadeType.REMOVE, CascadeType.ALL).contains(cascadeType)) {
65+
return;
66+
}
67+
loadEntity();
6768
Object child = field.get(entity);
6869
if (child != null) {
6970
if (Collection.class.isAssignableFrom(child.getClass())) {
70-
cascadeCollection(cascadeType, (Collection<?>) child);
71+
cascadeCollection((Collection<?>) child);
7172

7273
} else {
73-
cascadeItem(cascadeType, child);
74+
cascadeItem(child);
7475

7576
}
7677
}
7778

7879
}
7980

80-
private void cascadeItem(CascadeType cascadeType, Object child) {
81-
if (Arrays.asList(CascadeType.REMOVE, CascadeType.ALL).contains(cascadeType)) {
82-
mongoOperations.remove(child);
83-
}
81+
private void cascadeItem(Object child) {
82+
mongoOperations.remove(child);
8483
}
8584

86-
private void cascadeCollection(CascadeType cascadeType, Collection<?> child) {
87-
if (Arrays.asList(CascadeType.REMOVE, CascadeType.ALL).contains(cascadeType)) {
88-
child.parallelStream().forEach(mongoOperations::remove);
89-
}
85+
private void cascadeCollection(Collection<?> child) {
86+
child.parallelStream().forEach(mongoOperations::remove);
9087
}
9188

9289
public void doProcessing() {
93-
if (id == null || entity == null) {
90+
if (entity == null) {
9491
return;
9592
}
9693
ReflectionUtils.doWithFields(entity.getClass(), this);
9794
}
9895

96+
private void loadEntity() {
97+
if (!loaded) {
98+
Object sourceId = this.source.get("_id");
99+
if (sourceId != null) {
100+
ObjectId id = sourceId instanceof ObjectId ? (ObjectId) sourceId : new ObjectId((String) sourceId);
101+
Collection<?> findByIds = DatabaseOperations.findByIds(mongoOperations, entity.getClass(), id);
102+
this.entity = findByIds != null && !findByIds.isEmpty() ? findByIds.iterator().next() : null;
103+
}
104+
loaded = Boolean.TRUE;
105+
}
106+
}
107+
99108
}

src/main/java/io/github/kaiso/relmongo/events/processor/RelMongoProcessor.java

+29-16
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import org.springframework.beans.factory.annotation.Autowired;
2929
import org.springframework.data.mongodb.core.MongoOperations;
30+
import org.springframework.data.mongodb.core.mapping.Document;
3031
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
3132
import org.springframework.data.mongodb.core.mapping.event.AfterConvertEvent;
3233
import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent;
@@ -50,50 +51,62 @@ public class RelMongoProcessor extends AbstractMongoEventListener<Object> {
5051

5152
@Override
5253
public void onAfterLoad(AfterLoadEvent<Object> event) {
53-
PersistentPropertyLoadingCallback callback = new PersistentPropertyLoadingCallback(event.getSource());
54-
ReflectionUtils.doWithFields(event.getType(), callback);
55-
List<LoadableObjectsMetadata> loadableObjects = callback.getLoadableObjects();
56-
if (!loadableObjects.isEmpty()) {
57-
PersistentRelationResolver.resolveOnLoading(mongoOperations, loadableObjects, event.getSource());
54+
if (event.getType().isAnnotationPresent(Document.class)) {
55+
PersistentPropertyLoadingCallback callback = new PersistentPropertyLoadingCallback(event.getSource());
56+
ReflectionUtils.doWithFields(event.getType(), callback);
57+
List<LoadableObjectsMetadata> loadableObjects = callback.getLoadableObjects();
58+
if (!loadableObjects.isEmpty()) {
59+
PersistentRelationResolver.resolveOnLoading(mongoOperations, loadableObjects, event.getSource());
60+
}
5861
}
5962
super.onAfterLoad(event);
6063
}
6164

6265
@Override
6366
public void onBeforeSave(BeforeSaveEvent<Object> event) {
64-
PersistentPropertySavingCallback callback = new PersistentPropertySavingCallback(event.getDocument(), event.getCollectionName(), mongoOperations);
65-
ReflectionUtils.doWithFields(event.getSource().getClass(), callback);
67+
if (event.getSource().getClass().isAnnotationPresent(Document.class)) {
68+
PersistentPropertySavingCallback callback = new PersistentPropertySavingCallback(event.getDocument(), event.getCollectionName(), mongoOperations);
69+
ReflectionUtils.doWithFields(event.getSource().getClass(), callback);
70+
}
6671
super.onBeforeSave(event);
6772
}
6873

6974
@Override
7075
public void onBeforeConvert(BeforeConvertEvent<Object> event) {
71-
PersistentPropertyConvertingCallback callback = new PersistentPropertyConvertingCallback(event.getSource());
72-
ReflectionUtils.doWithFields(event.getSource().getClass(), callback);
76+
if (event.getSource().getClass().isAnnotationPresent(Document.class)) {
77+
PersistentPropertyConvertingCallback callback = new PersistentPropertyConvertingCallback(event.getSource());
78+
ReflectionUtils.doWithFields(event.getSource().getClass(), callback);
79+
}
7380
super.onBeforeConvert(event);
7481
}
7582

7683
@Override
7784
public void onAfterConvert(AfterConvertEvent<Object> event) {
78-
PersistentPropertyPostLoadingCallback callback = new PersistentPropertyPostLoadingCallback(event.getSource(), event.getDocument(), mongoOperations);
79-
ReflectionUtils.doWithFields(event.getSource().getClass(), callback);
85+
if (event.getSource().getClass().isAnnotationPresent(Document.class)) {
86+
PersistentPropertyPostLoadingCallback callback = new PersistentPropertyPostLoadingCallback(event.getSource(), event.getDocument(), mongoOperations);
87+
ReflectionUtils.doWithFields(event.getSource().getClass(), callback);
88+
}
8089
super.onAfterConvert(event);
8190
}
8291

8392
@Override
8493
public void onAfterSave(AfterSaveEvent<Object> event) {
8594
super.onAfterSave(event);
86-
PersistentPropertyPostSavingCallback callback = new PersistentPropertyPostSavingCallback(event.getSource(), mongoOperations);
87-
ReflectionUtils.doWithFields(event.getSource().getClass(), callback);
95+
if (event.getSource().getClass().isAnnotationPresent(Document.class)) {
96+
PersistentPropertyPostSavingCallback callback = new PersistentPropertyPostSavingCallback(event.getSource(), mongoOperations);
97+
ReflectionUtils.doWithFields(event.getSource().getClass(), callback);
98+
}
8899

89100
}
90101

91102
@Override
92103
public void onBeforeDelete(BeforeDeleteEvent<Object> event) {
93104
super.onBeforeDelete(event);
94-
PersistentPropertyCascadingRemoveCallback callback = new PersistentPropertyCascadingRemoveCallback(event.getDocument(), mongoOperations,
95-
event.getType());
96-
callback.doProcessing();
105+
if (event.getType().isAnnotationPresent(Document.class)) {
106+
PersistentPropertyCascadingRemoveCallback callback = new PersistentPropertyCascadingRemoveCallback(event.getDocument(), mongoOperations,
107+
event.getType());
108+
callback.doProcessing();
109+
}
97110
}
98111

99112
}

src/main/java/io/github/kaiso/relmongo/mongo/DocumentUtils.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package io.github.kaiso.relmongo.mongo;
1717

18+
import io.github.kaiso.relmongo.exception.RelMongoProcessingException;
1819
import io.github.kaiso.relmongo.util.RelMongoConstants;
1920

2021
import org.bson.Document;
@@ -60,7 +61,11 @@ private static boolean isDocumentLoaded(Document dbObject) {
6061
}
6162

6263
public static ObjectId mapIdentifier(Object object) {
63-
return ((org.bson.Document) object).getObjectId("_id");
64+
Object id = ((org.bson.Document) object).get("_id");
65+
if (id == null) {
66+
throw new RelMongoProcessingException("_id must not be null");
67+
}
68+
return id instanceof ObjectId ? (ObjectId) id : new ObjectId((String) id);
6469
}
6570

6671
}

src/main/java/io/github/kaiso/relmongo/util/ObjectIdReaderCallback.java

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package io.github.kaiso.relmongo.util;
1717

1818
import io.github.kaiso.relmongo.exception.RelMongoConfigurationException;
19-
import io.github.kaiso.relmongo.exception.RelMongoProcessingException;
2019

2120
import org.bson.types.ObjectId;
2221
import org.springframework.data.annotation.Id;

src/main/java/io/github/kaiso/relmongo/util/ReflectionsUtil.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ private ReflectionsUtil() {
3232

3333
public static Class<?> getGenericType(Field field) {
3434
if (Collection.class.isAssignableFrom(field.getType())) {
35-
return (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
35+
try {
36+
return (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
37+
} catch (ClassCastException e) {
38+
//do nothing if the generic type is also generic we do not take it into account
39+
}
3640
}
3741
return field.getType();
3842
}

src/test/java/io/github/kaiso/relmongo/data/model/Address.java

+14
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55

66
import org.bson.types.ObjectId;
77
import org.springframework.data.annotation.Id;
8+
import org.springframework.data.annotation.LastModifiedDate;
89
import org.springframework.data.mongodb.core.mapping.Document;
910

11+
import java.time.LocalDateTime;
12+
1013
@Document(collection = "addresses")
1114
public class Address {
1215

@@ -16,6 +19,9 @@ public class Address {
1619

1720
@ManyToOne(mappedBy = "addresses", fetch = FetchType.LAZY)
1821
private Person owner;
22+
23+
@LastModifiedDate
24+
private LocalDateTime lastModifiedDate;
1925

2026
public ObjectId getId() {
2127
return id;
@@ -32,4 +38,12 @@ public String getLocation() {
3238
public void setLocation(String location) {
3339
this.location = location;
3440
}
41+
42+
public LocalDateTime getLastModifiedDate() {
43+
return lastModifiedDate;
44+
}
45+
46+
public void setLastModifiedDate(LocalDateTime lastModifiedDate) {
47+
this.lastModifiedDate = lastModifiedDate;
48+
}
3549
}

0 commit comments

Comments
 (0)