Question

I subclassed org.apache.commons.beanutils.BeanUtilsBean so that it ignores NULL properties:

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

    }


}

My user class has a Collection of Stats:

public class User implements Serializable{

private Integer id;
private String username;
private Set<Stat> stats = new HashSet<Stat>();

}

If I do this it works fine:

    public void updateUser(User user) {        
    User dbUser = userDao.read(user.getId());
    dbUser.setUsername(user.getUsername());
    log.debug("about to save" + dbUser);
    userDao.update(dbUser);
}

But if I use copyProperties() it thinks that the Set of Stats is empty and tries to delete it:

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

I have tried using Hibernate.initialize(), as well as referring to the Set before and after using BeanUtils to init the Set (which it does if called before), but it doesn't matter because it is empty after (even if I re-init)... I also tried merging it into the Session but that didn't work either. Any thoughts? I'm thinking it might have to do with Hibernate creating a proxy object and BeanUtils somehow messing that up.

Was it helpful?

Solution

I think that the problem can be that "user" has an empty set (not null object), so copyProperties is copying the empty Set of "user" into the existing Set with values of "dbUser" (so, when you save the dbUser, you are cleaning the Set). If you want to prevent also the copy of and empty set, you can change your method to:

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

    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top