使用反射遍历对象的集合属性
Iterate through collection attribute of object with reflection
我正在尝试在我的代码中实施 this 解决方案,以在 spring 数据 mongodb 中进行级联保存。它适用于像这样的正常 class。
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 中,用于处理集合。我尝试了几件事但没有成功。除此之外,如果有另一种方法来完成这项任务,我们将不胜感激,即使这是一个单独的问题。
下面给出了我的监听器代码,与示例没有太大区别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());
}
}
}
}
}
});
}
}
我正在尝试在我的代码中实施 this 解决方案,以在 spring 数据 mongodb 中进行级联保存。它适用于像这样的正常 class。
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 中,用于处理集合。我尝试了几件事但没有成功。除此之外,如果有另一种方法来完成这项任务,我们将不胜感激,即使这是一个单独的问题。
下面给出了我的监听器代码,与示例没有太大区别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());
}
}
}
}
}
});
}
}