2015-08-28 96 views
1

我试图在我的代码中实现this解决方案在级联保存在春天的数据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这是在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; 
    } 
} 
} 

回答

0

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

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