先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" />