简单的应用程序与以下实体结构错误
@Entity(name="some_table")
@Inheritance(strategy= InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn( name="TYPE", discriminatorType=DiscriminatorType.STRING )
abstract class EntityBase {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column
private int id;
}
@Entity
@DiscriminatorValue("EntityA")
@Cacheable
class EntityA extends EntityBase {
@Column
private int aColumn;
...
}
@Entity
@DiscriminatorValue("EntityB")
@Cacheable
class EntityB extends EntityBase {
@Column
private int bColumn;
...
}
@Entity(name="holder_table")
@Cacheable
class HolderEntity {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column
private int id;
@ManyToOne(fetch=FetchType.LAZY)
EntityBase holdedEntity;
...
}
对于第一次加载或没有缓存,一切正常
从缓存加载HolderEntity实例后,由类型为EntityBase(抽象类)的对象初始化的holdedEntity字段。
伪代码:
def a = HolderEntity.get(1)
assert a.holdedEntity.class!=EntityBase //ok
a = HolderEntity.get(1) // load from cache
assert a.holdedEntity.class!=EntityBase //fails (actually EntityBase_$$_jvstbbe_0)
使用特殊逻辑从缓存hibernate构造实体加载期间:
对于字段,它通过变量类型(它的EntityBase类)而不是鉴别器(最终的Type [] types = subclassPersister.getPropertyTypes(); DefaultLoadEventListener )检测类类型并调用方法
SessionImpl.internalLoad(String entityName,Serializable id,boolean eager,boolean nullable)使用来自hibernate缓存的数据“实例化”抽象类和init字段
它适用于懒惰和放大渴望加载holdedEntity 类型存储在 AbstractEntityPersister.EntityMetamodel 中。看起来,缓存的字段类型是静态的,但它应该依赖于字段的实例
如何在不禁用hibernate L2缓存的情况下解决它?
Hibernate 4.3.8(4.3.6& 4.3.11也测试过)
更新: test class
答案 0 :(得分:3)
那是因为Hibernate使用代理进行惰性关联。如果要禁用代理,则需要将@Proxy注释添加到实体类映射中:
@Proxy(lazy=false)
如果你运行this GitHub test,那么你就是'看到@Proxy(lazy=false)
解决了你的问题。