我将org.apache.commons.beanutils.BeanUtilsBean子类化,以便忽略NULL属性:
public class NullAwareBeanUtilsBean extends BeanUtilsBean {
Logger log = Logger.getLogger(this.getClass());
@Override
public void copyProperty(Object dest, String name, Object value) throws IllegalAccessException, InvocationTargetException {
if (value == null) {
log.debug("skipping property " + name);
return;
}
super.copyProperty(dest, name, value);
}
}
我的用户类有一个Stats集合:
public class User implements Serializable{
private Integer id;
private String username;
private Set<Stat> stats = new HashSet<Stat>();
}
如果我这样做,它可以正常工作:
public void updateUser(User user) {
User dbUser = userDao.read(user.getId());
dbUser.setUsername(user.getUsername());
log.debug("about to save" + dbUser);
userDao.update(dbUser);
}
但是如果我使用copyProperties(),它认为Set of Stats是空的并试图删除它:
public void updateUser(User user) {
User dbUser = userDao.read(user.getId());
//the problem here is that hibernate does not like the copyProperties method...
try {
NullAwareBeanUtilsBean nullAwareBeanUtilsBean = new NullAwareBeanUtilsBean();
nullAwareBeanUtilsBean.copyProperties(dbUser, user);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//dbUser = (User) userDao.getCurrentSession().merge(dbUser);
//log.debug("stats size=" + dbUser.getStats().size());
log.debug("about to save" + dbUser);
userDao.update(dbUser); }
我已经尝试过使用Hibernate.initialize(),以及在使用BeanUtils之前和之后引用Set来初始化Set(如果之前调用它会这样做),但它并不重要,因为它是空的之后(即使我重新初始化)...我也尝试将它合并到会话中,但这也没有用。有什么想法吗?我认为它可能与Hibernate创建一个代理对象有关,而BeanUtils却以某种方式弄乱了它。
答案 0 :(得分:0)
我认为问题可能是“user”有一个空集(非null对象),因此copyProperties将空的“user”集复制到现有的Set中,其值为“dbUser”(所以,当你保存dbUser,你正在清理Set)。如果您还想要防止复制和空集,可以将方法更改为:
public void copyProperty(Object dest, String name, Object value) throws IllegalAccessException, InvocationTargetException {
if (value == null) {
log.debug("skipping property " + name);
return;
}
if ((value instanceof Set) && ((Set) value).isEmpty()) {
log.debug("skipping empty Set" + name);
return;
}
super.copyProperty(dest, name, value);
}