通过反射遍历对象的collection属性

通过反射遍历对象的collection属性

我正在尝试在有关级联保存Spring数据mongodb的代码中实现this解决方案。它适用于像这样的普通班。

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中提供给集合工作的link中的代码。我尝试了几件事,但没有成功。除此之外,如果有另一种方法可以完成此任务,即使这是一个单独的问题,也将不胜感激。

我的侦听器代码如下所示,与示例链接没有太大区别。

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());
                        }
                    }
                }
            }
        }
    });
  }
}

关于java - 通过反射遍历对象的collection属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32280540/

10-08 23:34