我的域模型中有一个层次结构,由类描述:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class BaseEntity {
@Id
private Long id;
// other fields
}
@DiscriminatorValue(value = "Individual")
public class IndividualEntity extends BaseEntity {
// fields
}
@DiscriminatorValue(value = "Branch")
public class BranchEntity extends BaseEntity {
// fields
}
我正在抓取这样的对象:
Specification<BaseEntity> specification = createSpecification();
BaseEntity entity = baseRepository.findOne(specification);
(我使用的是弹簧数据)
问题是Hibernate返回代理对象(我理解的),但代理是BaseEntity
,而不是正确的子类(它的&#39;类是BaseEntity_$$_jvsted9_26
,因此{{1}是假的。
有趣的是,并非所有对象都作为代理返回
我在循环中获取实体(常见事务),其中一些以正常形式返回(即entity instanceof IndividualEntity
/ IndividualEntity
),一些作为代理返回。
如果我改变机制,那么每次获取都在单独的事务中完成 - 根本不返回代理对象。
我知道我可以解开那个代理(例如像here),但这种行为的原因是什么(对我来说有点奇怪),我可以避免吗?
答案 0 :(得分:4)
不能确定没有看到更多的对象模型,但是Hibernate这样做的原因之一是,是否必须在会话开始时已将BaseEntity解析为同一BaseEntity.id
的代理。 / p>
例如,如果存在另一个与BaseEntity
具有ToOne关系的类,则它将仅具有id
的外键,因此将使用BaseEntity_$$...
代理来延迟为另一端解析正确的子类。然后,这成为在休眠id
中管理的PersistenceContext
的实例。
很显然,Hibernate.unwrap()
或上面链接中的其他选项之一将显示'true'实例。另一种选择是在BaseEntity
(例如isIndividual()
)上使用抽象方法。这看起来可能比较整洁,但是最终,在调用该方法时,Hibernate仍然需要解析代理。