Question

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.

Was it helpful?

Solution 2

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

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

OTHER TIPS

You can get the underlying class from the proxy by doing this:

if (user instanceof HibernateProxy) {
    user = (User) ((HibernateProxy) user).getHibernateLazyInitializer().getImplementation();
}

Note that if the object has not been initialized by hibernate (a lazily loaded association, for instance), you need to first initialize it:

Hibernate.initialize(entity);

Another option is to use Hibernate.getClass(user)

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