通过反射迭代对象的集合属性



我试图在我的代码中实现这个解决方案,关于在春季数据mongodb级联保存。它适用于这样的普通类。

public class Test{
    @Id
    private String id;
    @DBRef
    @CascadeSave
    private Contact contact;
}

但是我有这样的东西

public class Test{
    @Id
    private String id;
    @DBRef
    @CascadeSave
    private Set<Contact> contacts = new HashSet<>();
}

我想改变在listener的代码,这是在我已经给出了与集合工作的链接。我试了好几次,都没有成功。除此之外,如果有其他方法完成这项任务,我将不胜感激,即使这是一个单独的问题。

下面给出了我的侦听器代码,它与示例链接没有太大区别。

public class CascadingMongoEventListener extends AbstractMongoEventListener {
private static final Logger logger = LoggerFactory.getLogger(CascadingMongoEventListener.class);
@Autowired
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);
            try {
                if (field.isAnnotationPresent(DBRef.class) && field.isAnnotationPresent(CascadeSave.class)) {
                    final Object fieldValue = field.get(source);
                    if (fieldValue != null) {
                        if (Collection.class.isAssignableFrom(field.getType())) {
                            @SuppressWarnings("unchecked")
                            Collection models = (Collection) fieldValue;
                            for (Object model : models) {
                               mongoOperations.save(model);
                            }
                        } else {
                            mongoOperations.save(fieldValue);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
        }
    });
}
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;
    }
}
}

这是为我工作的解决方案,我将感谢任何改进的建议。

public class CascadingMongoEventListener extends AbstractMongoEventListener {
private static final Logger logger = LoggerFactory.getLogger(CascadingMongoEventListener.class);
@Autowired
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 != null) {
                Object fieldValue = field.get(source);
                if (field.isAnnotationPresent(DBRef.class) && field.isAnnotationPresent(CascadeSave.class)) {
                    if (Collection.class.isAssignableFrom(fieldValue.getClass())) {
                        Collection<Object> collection = (Collection<Object>) fieldValue;
                        for (Object item : collection) {
                            if (mongoOperations.collectionExists(item.getClass())) {
                                mongoOperations.save(item);
                                logger.debug("Set of {}s saved.", item.getClass().getSimpleName());
                            }
                        }
                    } else {
                        if (mongoOperations.collectionExists(fieldValue.getClass())) {
                            mongoOperations.save(fieldValue);
                            logger.debug("{} saved.", fieldValue.getClass().getSimpleName());
                        }
                    }
                }
            }
        }
    });
  }
}

相关内容

  • 没有找到相关文章