我正在使用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
对象。
答案 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)