带有二级缓存的 Hibernate 6.2+ 会忽略急切加载

问题描述 投票:0回答:1

我有一个使用 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>

我有带有

@ManyToOne(fetch = FetchType.EAGER)
和缓存的实体。我知道预加载是一种反模式,但软件很复杂,目前无法更改。

@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
的结果中延迟加载,并且是一个休眠代理对象。

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

Hibernate 6.2 并禁用二级缓存

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

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

Hibernate 6.1 并启用二级缓存

当我将 Hibernate 版本更改为 6.1.7.Final 并启用二级缓存时,结果按预期急切加载。

休眠 6.4.0.CR1

与 6.2 相同的问题

我不确定这是一个错误还是缓存的预期变化?但是,我在 hibernate 6.2 迁移指南中没有找到任何有关此内容的信息。我该如何处理这个问题,我需要在启用二级缓存的情况下急切加载结果。

hibernate caching eager-loading
1个回答
0
投票

我在Hibernate论坛得到了答案:

仅仅因为您看到为关联设置了代理对象并不意味着它是延迟加载的。有时 Hibernate ORM 出于其他原因需要使用代理,但会确保对象作为加载操作的一部分进行初始化。

Hibernate 论坛中的

Thread,其中包含 Jackson 的提示。

© www.soinside.com 2019 - 2024. All rights reserved.