Hibernate返回基类的代理

pne*_*ior 6 java orm hibernate spring-data-jpa

我的域模型中有一个层次结构,由类描述:

@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
}
Run Code Online (Sandbox Code Playgroud)

我正在获取这样的对象:

Specification<BaseEntity> specification = createSpecification();
BaseEntity entity = baseRepository.findOne(specification);
Run Code Online (Sandbox Code Playgroud)

(我正在使用spring-data)

问题是Hibernate返回代理对象(我理解),但代理是BaseEntity,而不是正确的子类(它的'类是BaseEntity_$$_jvsted9_26,因此entity instanceof IndividualEntity是假的).

有趣的是,并非所有对象都作为代理返回.
我在循环中获取实体(常见事务),其中一些以正常形式(即IndividualEntity/ BranchEntity)返回,一些以代理方式返回.
如果我改变机制,那么每次获取都是在单独的事务中完成的 - 根本不返回任何代理对象.

我知道我可以解开那个代理(例如像这里),但这种行为的原因是什么(对我来说有点奇怪),我可以避免它吗?

df7*_*899 4

在没有看到更多对象模型的情况下无法确定,但 Hibernate 这样做的原因之一是,如果 BaseEntity 已经必须BaseEntity.id在会话早期被解析为同一对象的代理。

例如,如果有另一个类与 a 具有 ToOne 关系BaseEntity,则它只有一个外键id,因此将使用BaseEntity_$$...代理来延迟解析另一端的正确子类。id然后,这将成为Hibernate 中管理的实例PersistenceContext

显然Hibernate.unwrap(),上面链接中的 或其他选项之一将显示“真实”实例。BaseEntity另一种选择是在(例如)上使用抽象方法isIndividual()。这可能看起来更整洁,但最终 Hibernate 仍然需要在调用该方法时解析代理。