I have project with hibernate 6.2.13.Final and jcache/ehcache for 2nd level cache:
<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>
And I have entities with @ManyToOne(fetch = FetchType.EAGER)
and caching. I know that Eager Loading is an anti-pattern, but the software is complex and it’s not possible to change that at the moment.
@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;
}
}
When I query an entry, everything is fine.
entityManager.find(Foo.class, id);
However, when I query multiple entries, the FooType
is lazy loaded in the results of Foo
and is a hibernate proxy object.
final TypedQuery<Foo> fooQuery = entityManager.createQuery("FROM Foo f", Foo.class);
final List<Foo> fooList = fooQuery.getResultList();
Hibernate 6.2 and disabled 2nd level cache
When I deactivate the 2nd level cache, the result is eagerly loaded as expected.
<property name="hibernate.cache.use_second_level_cache" value="false" />
Hibernate 6.1 and enabled 2nd level cache
When I change the Hibernate version to 6.1.7.Final and the 2nd level cache is enabled, the result loads eagerly as expected.
Hibernate 6.4.0.CR1
Same issue like 6.2
I’m not sure if this is a bug or an expected change in caching? However, I did not find anything about this in the hibernate 6.2 migration guide. How can I handle this issue, I need the result eager loaded with 2nd level cache enabled.