Search code examples
javahibernatereflectionproxyjavassist

Hibernate & javaassist proxy / lazy initialization causing errors with reflection


I'm using Hibernate 4 and am trying to use reflection to access a field from an entity just loaded from the DB. However, retrieving the field value via reflection returns a value of null even though the entity's field actually has a value.

After doing a little debugging, I see that the entity retrieved is a javassist proxy to the entity. I am presuming the problem is due to lazy loading of the entity, but am not sure how to fix the problem.

@Entity
public class User
{

  @Id
  @GeneratedValue(strategy=GenerationType.TABLE, generator="UUIDGenerator")
  @Column(name="id")
  private Long id;

  @NotNull
  private String username;
  private String password;

  @Version
  @Column(name="version")
  private Integer version;
}


public User updateUser(long userId, User user) {
    // first need to find the user in the db
    User u = checkNotNull( userRepository.findOne(userId) );

    // get the version field
    Field field = User.class.getDeclaredField("version");

    // check that the versions of the two objects match
    ReflectionUtils.makeAccessible(field);
    Object targetVersion = checkNotNull( ReflectionUtils.getField(field, u) );

    return u;
}

In the debugger, I see that u is actually of type class com.ia.domain.User_$$_jvst8cf_3 and not com.ia.domain.User. If I drill-down on the var and inspect the version field, it is listed as null. However u.getVersion() will retrieve a proper value.

Is there anyway to get the value via reflection? Do I have to handle the case of it being a proxy object differently? I would rather not need to know about the existence of a proxy object if possible, and just treat the retrieved object as a User object which it is supposed to be.


Solution

  • I have successfully used PropertyUtilsBean (apache commons beanutils) to retrieve the field value:

    PropertyUtilsBean beanUtil = new PropertyUtilsBean();
    beanUtil.getProperty(entity, propertyName);