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 bd2087b

Browse files
committed
HHH-19734 Test shallow query caching with proxy presence of bytecode enhanced model
1 parent 193b15c commit bd2087b

File tree

3 files changed

+180
-5
lines changed

3 files changed

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

‎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
@@ -40,6 +40,7 @@ public class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
4040
private List<String> mappingFiles;
4141
private List<String> managedClassNames;
4242
private boolean excludeUnlistedClasses;
43+
private ClassLoader classLoader;
4344

4445
public PersistenceUnitInfoImpl(String name) {
4546
this.name = name;
@@ -120,6 +121,15 @@ public void setExcludeUnlistedClasses(boolean excludeUnlistedClasses) {
120121
this.excludeUnlistedClasses = excludeUnlistedClasses;
121122
}
122123

124+
@Override
125+
public ClassLoader getClassLoader() {
126+
return classLoader;
127+
}
128+
129+
public void setClassLoader(ClassLoader classLoader) {
130+
this.classLoader = classLoader;
131+
}
132+
123133
@Override
124134
public String getPersistenceXMLSchemaVersion() {
125135
return null;
@@ -145,11 +155,6 @@ public URL getPersistenceUnitRootUrl() {
145155
return null;
146156
}
147157

148-
@Override
149-
public ClassLoader getClassLoader() {
150-
return null;
151-
}
152-
153158
@Override
154159
public void addTransformer(ClassTransformer transformer) {
155160

‎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
@@ -90,6 +90,9 @@ public static EntityManagerFactoryScope findEntityManagerFactoryScope(
9090
pui.getProperties().put( key, value )
9191
);
9292

93+
// Use the context class loader for entity loading if configured,
94+
// to make enhancement work for tests
95+
pui.setClassLoader( Thread.currentThread().getContextClassLoader() );
9396
pui.setTransactionType( emfAnn.transactionType() );
9497
pui.setCacheMode( emfAnn.sharedCacheMode() );
9598
pui.setValidationMode( emfAnn.validationMode() );

0 commit comments

Comments
(0)

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