先show一下用法
@CreatedDate
private DateTime createdDate;
@LastModifiedDate
private DateTime lastModifiedDate;
@DBRef
@CascadeSave
private AlarmDetails alarmDetails;
1。 先自定@CascadeSave annoation
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface CascadeSave {
}
2。再定义listener
import java.lang.reflect.Field;
import javax.inject.Inject;
import org.springframework.data.annotation.Id;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.util.ReflectionUtils;
@SuppressWarnings("rawtypes")
public class CascadingMongoEventListener extends AbstractMongoEventListener {
@Inject
private MongoOperations mongoOperations;
@Override
public void onBeforeConvert(final Object source) {
ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
ReflectionUtils.makeAccessible(field);
if (field.isAnnotationPresent(DBRef.class) && field.isAnnotationPresent(CascadeSave.class)) {
final Object fieldValue = field.get(source);
if (fieldValue == null) {
return;
}
DbRefFieldCallback callback = new DbRefFieldCallback();
ReflectionUtils.doWithFields(fieldValue.getClass(), callback);
if (!callback.isIdFound()) {
throw new MappingException("Cannot perform cascade save on child object without id set");
}
mongoOperations.save(fieldValue);
}
}
});
}
private static class DbRefFieldCallback implements ReflectionUtils.FieldCallback {
private boolean idFound;
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
ReflectionUtils.makeAccessible(field);
if (field.isAnnotationPresent(Id.class)) {
idFound = true;
}
}
public boolean isIdFound() {
return idFound;
}
}
}
3。别忘了配置
<mongo:auditing/>
<mongo:mongo host="${db.mongo.host}" port="${db.mongo.port}" />
<mongo:db-factory dbname="${db.mongo.name}" mongo-ref="mongo"/>
<bean class="com.eifesun.monitor.web.model.mongodb.CascadingMongoEventListener" />