繁体   English   中英

Hibernate继承和二级缓存代理

[英]Hibernate inheritance and 2nd level cache proxies

简单的应用程序与下面的实体结构错误

@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类)而不是鉴别器( final Type [] types = subclassPersister.getPropertyTypes();DefaultLoadEventListener中 )和调用方法检测类类型
SessionImpl.internalLoad(String entityName,Serializable id,boolean eager,boolean nullable)通过来自hibernate缓存的数据“实例化”抽象类和init字段

它适用于存储在AbstractEntityPersister.EntityMetamodel中的holdedEntity类类型的延迟和急切加载。 看起来,缓存的字段类型是静态的,但它应该依赖于字段的实例

如何在不禁用hibernate L2缓存的情况下解决它?

Hibernate 4.3.8(也测试了4.3.6和4.3.11)

更新: 测试类

那是因为Hibernate使用代理进行惰性关联。 如果要禁用代理,则需要将@Proxy批注添加到实体类映射中:

@Proxy(lazy=false)

如果你运行这个GitHub测试 ,你会发现@Proxy(lazy=false)解决了你的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM