![](/img/trans.png)
[英]spring data mongodb Cannot perform cascade save on child object without id set
[英]cascade save in spring data and mongodb
我正在實現一個基於spring數據和mongodb的應用程序。
@Document
public class User {
@Id
private ObjectId id;
private String name;
private Integer age;
@DBRef
private Address address;
@DBRef
@CascadeSave
private Set<Action> actions = new HashSet<Action>();
我需要將操作列表作為嵌入式文檔保存到用戶中,為此我實現了自定義級聯保存
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CascadeSave {
}
CascadingMongoEventListener.java
public class CascadingMongoEventListener extends AbstractMongoEventListener<Object> {
@Autowired
private MongoOperations mongoOperations;
@Override
public void onBeforeConvert(final BeforeConvertEvent<Object> event) {
final Object source = event.getSource();
ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {
@Override
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 instanceof List<?>) {
for (Object item : (List<?>) fieldValue) {
checkNSave(item);
}
} else {
checkNSave(fieldValue);
}
}
}
});
}
private void checkNSave(Object fieldValue) {
DbRefFieldCallback callback = new DbRefFieldCallback();
ReflectionUtils.doWithFields(fieldValue.getClass(), callback);
if (!callback.isIdFound()) {
throw new MappingException("Oops, something went wrong. Child doesn't have @Id?");
}
mongoOperations.save(fieldValue);
}
private static class DbRefFieldCallback implements ReflectionUtils.FieldCallback {
private boolean idFound;
@Override
public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException {
ReflectionUtils.makeAccessible(field);
if (field.isAnnotationPresent(Id.class)) {
idFound = true;
}
}
public boolean isIdFound() {
return idFound;
}
}
}
我嘗試用操作列表保存用戶
Action action = new Action();
action.setDescription("des");
action.setTime(ZonedDateTime.now());
User personHektor = new User();
personHektor.setName("Hektor");
personHektor.setActions(Stream.of(action).collect(Collectors.toSet()));
personRepo.save(personHektor);
但是我有這個錯誤
org.springframework.data.mapping.MappingException:糟糕,出了點問題。 孩子沒有@Id?
我在github中推送了該項目以提高知名度
盡管CascadingMongoEventListener
實際上是Set
但它會根據List
檢查fieldValue 。
將其更改(可能是Collection
),然后MappingException
將消失。
為了進一步解決ZonedDateTime
的問題,請注冊一個Converter
以進行轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.