带二级缓存的Hibernate 6.2+忽略了即时加载

pkwftd7m  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(83)

我有一个项目,使用了Hibernate 6.2.13.Final和jcache/ehcache作为二级缓存:

<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>6.2.13.Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-envers</artifactId>
    <version>6.2.13.Final</version>
</dependency>

<!-- API for 2nd Level Cache -->
<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-jcache</artifactId>
    <version>6.2.13.Final</version>
</dependency>
<!-- Implementation for 2nd Level Cache -->
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <classifier>jakarta</classifier>
    <version>3.10.8</version>
</dependency>

字符串
我知道Eager Loading是一个反模式,但软件很复杂,目前还不可能改变它。

@Entity
@Cacheable
@Audited
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class FooType {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid2")
    @Size(max = 36)
    @Column(length = 36)
    @UserInterface(showInForm = false, showInList = false)
    @Comment("Primary key")
    private String id;

    @Version
    @NotNull
    @UserInterface(showInForm = false, showInList = false)
    @Comment("Version column for optimistic locking")
    private int version;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }
}
@Entity
@Cacheable
@Audited
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Foo {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid2")
    @Size(max = 36)
    @Column(length = 36)
    @UserInterface(showInForm = false, showInList = false)
    @Comment("Primary key")
    private String id;

    @Version
    @NotNull
    @UserInterface(showInForm = false, showInList = false)
    @Comment("Version column for optimistic locking")
    private int version;
    
    @ManyToOne(fetch = FetchType.EAGER)
    private FooType;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }
    
    public FooType getFooType() {
        return fooType;
    }
    
    public void setFooType(FooType fooType) {
        this.fooType = fooType;
    }
}

的数据
当我查询一个条目时,一切都很好。

entityManager.find(Foo.class, id);


但是,当我查询多个条目时,FooType是延迟加载到Foo的结果中的,并且是一个hibernate代理对象。

final TypedQuery<Foo> fooQuery = entityManager.createQuery("FROM Foo f", Foo.class);
final List<Foo> fooList = fooQuery.getResultList();

休眠6.2并禁用二级缓存

当我停用第二级缓存时,结果会按预期的那样急切地加载。

<property name="hibernate.cache.use_second_level_cache" value="false" />

Hibernate 6.1并启用二级缓存

当我将Hibernate版本更改为6.1.7.Final并启用二级缓存时,结果会像预期的那样迅速加载。

Hibernate 6.4.0.CR1

与6.2类似的问题
我不确定这是一个bug还是缓存中的预期变化?但是,我在Hibernate 6.2迁移指南中没有找到任何关于这个问题的内容。我如何处理这个问题,我需要在启用二级缓存的情况下加载结果。

ddhy6vgd

ddhy6vgd1#

我在Hibernate论坛上找到了答案:
仅仅因为你看到一个代理对象被设置为关联并不意味着它是延迟加载的。有时候Hibernate ORM需要与代理一起工作,但会确保对象在加载操作中被初始化。
Hibernate论坛中的Thread,带有对Jackson的提示。

相关问题