Hibernate& javaassist proxy / lazy初始化导致反射错误

时间:2014-04-18 04:11:34

标签: java hibernate reflection proxy javassist

我正在使用Hibernate 4并尝试使用反射来访问刚刚从DB加载的实体中的字段。但是,通过反射检索字段值会返回null值,即使实体的字段实际上有值。

在做了一点调试之后,我发现检索到的实体是实体的javassist代理。我假设问题是由于实体的延迟加载,但我不确定如何解决问题。

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

在调试器中,我看到u实际上是class com.ia.domain.User_$$_jvst8cf_3类型,而不是com.ia.domain.User。如果我深入查看var并检查version字段,则会将其列为null。但是u.getVersion()将检索正确的值。

无论如何通过反思获得价值?我是否必须以不同的方式处理它作为代理对象的情况?如果可能的话,我宁愿不需要知道代理对象的存在,只需将检索到的对象视为它应该是的User对象。

3 个答案:

答案 0 :(得分:4)

您可以通过以下方式从代理获取基础类:

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

请注意,如果对象尚未被hibernate初始化(例如,延迟加载的关联),则需要先对其进行初始化:

Hibernate.initialize(entity);

答案 1 :(得分:1)

我已成功使用PropertyUtilsBean(apache commons beanutils)来检索字段值:

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

答案 2 :(得分:0)

另一个选择是使用Hibernate.getClass(user)