Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2b14963

Browse files
committed
HHH-19734 Test shallow query caching with proxy presence of bytecode enhanced model
1 parent 0800a96 commit 2b14963

File tree

3 files changed

+176
-5
lines changed

3 files changed

+176
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.jpa.query;
6+
7+
import jakarta.persistence.Entity;
8+
import jakarta.persistence.EntityManager;
9+
import jakarta.persistence.Id;
10+
import jakarta.persistence.TypedQuery;
11+
import org.hibernate.annotations.Cache;
12+
import org.hibernate.annotations.CacheConcurrencyStrategy;
13+
import org.hibernate.annotations.CacheLayout;
14+
import org.hibernate.annotations.QueryCacheLayout;
15+
import org.hibernate.cfg.AvailableSettings;
16+
import org.hibernate.engine.spi.SessionFactoryImplementor;
17+
import org.hibernate.stat.Statistics;
18+
import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced;
19+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
20+
import org.hibernate.testing.orm.junit.JiraKey;
21+
import org.hibernate.testing.orm.junit.Jpa;
22+
import org.hibernate.testing.orm.junit.Setting;
23+
import org.junit.jupiter.api.AfterEach;
24+
import org.junit.jupiter.api.BeforeEach;
25+
import org.junit.jupiter.api.Test;
26+
27+
import static org.hibernate.jpa.HibernateHints.HINT_CACHEABLE;
28+
import static org.junit.jupiter.api.Assertions.assertEquals;
29+
30+
@JiraKey("HHH-19734")
31+
@Jpa(
32+
annotatedClasses = {
33+
CachedQueryShallowWithDiscriminatorBytecodeEnhancedTest.Person.class
34+
},
35+
generateStatistics = true,
36+
properties = {
37+
@Setting(name = AvailableSettings.USE_QUERY_CACHE, value = "true"),
38+
@Setting(name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true")
39+
}
40+
)
41+
@BytecodeEnhanced
42+
public class CachedQueryShallowWithDiscriminatorBytecodeEnhancedTest {
43+
44+
public final static String HQL = "select p from Person p";
45+
46+
@BeforeEach
47+
public void setUp(EntityManagerFactoryScope scope) {
48+
scope.inTransaction(
49+
em -> {
50+
Person person = new Person( 1L );
51+
person.setName( "Bob" );
52+
em.persist( person );
53+
}
54+
);
55+
}
56+
57+
@AfterEach
58+
public void tearDown(EntityManagerFactoryScope scope) {
59+
scope.getEntityManagerFactory().getSchemaManager().truncate();
60+
}
61+
62+
@Test
63+
public void testCacheableQuery(EntityManagerFactoryScope scope) {
64+
65+
Statistics stats = getStatistics( scope );
66+
stats.clear();
67+
68+
// First time the query is executed, query and results are cached.
69+
scope.inTransaction(
70+
em -> {
71+
loadPersons( em );
72+
73+
assertThatAnSQLQueryHasBeenExecuted( stats );
74+
75+
assertEquals( 0, stats.getQueryCacheHitCount() );
76+
assertEquals( 1, stats.getQueryCacheMissCount() );
77+
assertEquals( 1, stats.getQueryCachePutCount() );
78+
79+
assertEquals( 0, stats.getSecondLevelCacheHitCount() );
80+
assertEquals( 0, stats.getSecondLevelCacheMissCount() );
81+
assertEquals( 0, stats.getSecondLevelCachePutCount() );
82+
}
83+
);
84+
85+
stats.clear();
86+
87+
// Second time the query is executed, list of entities are read from query cache
88+
89+
scope.inTransaction(
90+
em -> {
91+
// Create a person proxy in the persistence context to trigger the HHH-19734 error
92+
em.getReference( Person.class, 1L );
93+
94+
loadPersons( em );
95+
96+
assertThatNoSQLQueryHasBeenExecuted( stats );
97+
98+
assertEquals( 1, stats.getQueryCacheHitCount() );
99+
assertEquals( 0, stats.getQueryCacheMissCount() );
100+
assertEquals( 0, stats.getQueryCachePutCount() );
101+
102+
assertEquals( 1, stats.getSecondLevelCacheHitCount() );
103+
assertEquals( 0, stats.getSecondLevelCacheMissCount() );
104+
assertEquals( 0, stats.getSecondLevelCachePutCount() );
105+
}
106+
);
107+
108+
}
109+
110+
private static Statistics getStatistics(EntityManagerFactoryScope scope) {
111+
return ((SessionFactoryImplementor) scope.getEntityManagerFactory()).getStatistics();
112+
}
113+
114+
private static void loadPersons(EntityManager em) {
115+
TypedQuery<Person> query = em.createQuery( HQL, Person.class )
116+
.setHint( HINT_CACHEABLE, true );
117+
Person person = query.getSingleResult();
118+
assertEquals( 1L, person.getId() );
119+
assertEquals( "Bob", person.getName() );
120+
}
121+
122+
private static void assertThatAnSQLQueryHasBeenExecuted(Statistics stats) {
123+
assertEquals( 1, stats.getQueryStatistics( HQL ).getExecutionCount() );
124+
}
125+
126+
private static void assertThatNoSQLQueryHasBeenExecuted(Statistics stats) {
127+
assertEquals( 0, stats.getQueryStatistics( HQL ).getExecutionCount() );
128+
}
129+
130+
@Entity(name = "Person")
131+
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
132+
@QueryCacheLayout(layout = CacheLayout.SHALLOW)
133+
public static class Person {
134+
@Id
135+
private Long id;
136+
private String name;
137+
138+
public Person() {
139+
super();
140+
}
141+
142+
public Person(Long id) {
143+
this.id = id;
144+
}
145+
146+
public Long getId() {
147+
return id;
148+
}
149+
150+
public void setId(Long id) {
151+
this.id = id;
152+
}
153+
154+
public String getName() {
155+
return name;
156+
}
157+
158+
public void setName(String name) {
159+
this.name = name;
160+
}
161+
}
162+
163+
}

‎hibernate-testing/src/main/java/org/hibernate/testing/orm/jpa/PersistenceUnitInfoImpl.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
4444
private List<String> mappingFiles;
4545
private List<String> managedClassNames;
4646
private boolean excludeUnlistedClasses;
47+
private ClassLoader classLoader;
4748

4849
public PersistenceUnitInfoImpl(String name) {
4950
this.name = name;
@@ -142,6 +143,15 @@ public void setExcludeUnlistedClasses(boolean excludeUnlistedClasses) {
142143
this.excludeUnlistedClasses = excludeUnlistedClasses;
143144
}
144145

146+
@Override
147+
public ClassLoader getClassLoader() {
148+
return classLoader;
149+
}
150+
151+
public void setClassLoader(ClassLoader classLoader) {
152+
this.classLoader = classLoader;
153+
}
154+
145155
@Override
146156
public String getPersistenceXMLSchemaVersion() {
147157
return null;
@@ -167,11 +177,6 @@ public URL getPersistenceUnitRootUrl() {
167177
return null;
168178
}
169179

170-
@Override
171-
public ClassLoader getClassLoader() {
172-
return null;
173-
}
174-
175180
@Override
176181
public void addTransformer(ClassTransformer transformer) {
177182

‎hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/EntityManagerFactoryExtension.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ private static void collectProperties(PersistenceUnitInfoImpl pui, Jpa jpa) {
111111
private static PersistenceUnitInfoImpl createPersistenceUnitInfo(Jpa jpa) {
112112
final PersistenceUnitInfoImpl pui =
113113
new PersistenceUnitInfoImpl( jpa.persistenceUnitName() );
114+
// Use the context class loader for entity loading if configured,
115+
// to make enhancement work for tests
116+
pui.setClassLoader( Thread.currentThread().getContextClassLoader() );
114117
pui.setTransactionType( jpa.transactionType() );
115118
pui.setCacheMode( jpa.sharedCacheMode() );
116119
pui.setValidationMode( jpa.validationMode() );

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /