HHH-16617 Add test for issue
This commit is contained in:
parent
13662e7c7a
commit
a4acdce2fa
|
@ -1,148 +0,0 @@
|
|||
package org.hibernate.orm.test.cache;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.Filter;
|
||||
import org.hibernate.annotations.FilterDef;
|
||||
import org.hibernate.annotations.ParamDef;
|
||||
import org.hibernate.cache.spi.RegionFactory;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.stat.CacheRegionStatistics;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DomainModel(annotatedClasses = {
|
||||
QueryCacheWithFilterTest.Person.class,
|
||||
})
|
||||
@SessionFactory(generateStatistics = true)
|
||||
@ServiceRegistry(
|
||||
settings = {
|
||||
@Setting(name = AvailableSettings.USE_QUERY_CACHE, value = "true"),
|
||||
@Setting(name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true")
|
||||
}
|
||||
)
|
||||
public class QueryCacheWithFilterTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Person p = new Person();
|
||||
p.setName( "John" );
|
||||
session.persist( p );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryKeyIsImmutable(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.enableFilter( "personName" )
|
||||
.setParameter( "name", "John" );
|
||||
Query<Person> query = session.createQuery(
|
||||
"from Person p",
|
||||
Person.class
|
||||
);
|
||||
query.setCacheable( true );
|
||||
|
||||
List<Person> resultList = query.getResultList();
|
||||
assertThat( resultList ).hasSize( 1 );
|
||||
|
||||
//cache query should not be affected by the additional filter
|
||||
session.enableFilter( "personName2" )
|
||||
.setParameter( "name", "John" );
|
||||
}
|
||||
);
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.enableFilter( "personName" )
|
||||
.setParameter( "name", "John" );
|
||||
Query<Person> query = session.createQuery(
|
||||
"from Person p",
|
||||
Person.class
|
||||
);
|
||||
query.setCacheable( true );
|
||||
|
||||
List<Person> resultList = query.getResultList();
|
||||
assertThat( resultList ).hasSize( 1 );
|
||||
|
||||
assertThat( getQueryCacheRegionStatistics( session ).getHitCount() ).isEqualTo( 1 );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private static CacheRegionStatistics getQueryCacheRegionStatistics(SessionImplementor session) {
|
||||
StatisticsImplementor statistics = session.getSessionFactory().getStatistics();
|
||||
return statistics.getQueryRegionStatistics( RegionFactory.DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME );
|
||||
}
|
||||
|
||||
|
||||
@Entity(name = "Person")
|
||||
@FilterDef(
|
||||
name = "personName",
|
||||
parameters = @ParamDef(
|
||||
name = "name",
|
||||
type = String.class
|
||||
)
|
||||
)
|
||||
@Filter(
|
||||
name = "personName",
|
||||
condition = "name = :name"
|
||||
)
|
||||
@FilterDef(
|
||||
name = "personName2",
|
||||
parameters = @ParamDef(
|
||||
name = "name",
|
||||
type = String.class
|
||||
)
|
||||
)
|
||||
@Filter(
|
||||
name = "personName2",
|
||||
condition = "name = :name"
|
||||
)
|
||||
public static class Person {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.test.querycache;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.Filter;
|
||||
import org.hibernate.annotations.FilterDef;
|
||||
import org.hibernate.annotations.ParamDef;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.Jira;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DomainModel( annotatedClasses = QueryCacheWithFilterTest.Person.class )
|
||||
@SessionFactory( generateStatistics = true )
|
||||
@ServiceRegistry( settings = {
|
||||
@Setting( name = AvailableSettings.USE_QUERY_CACHE, value = "true" ),
|
||||
@Setting( name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true" )
|
||||
} )
|
||||
public class QueryCacheWithFilterTest {
|
||||
@BeforeAll
|
||||
public void setUp(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> session.persist( new Person( "John" ) ) );
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> session.createMutationQuery( "delete from Person" ).executeUpdate() );
|
||||
}
|
||||
|
||||
@Test
|
||||
@Jira( "https://hibernate.atlassian.net/browse/HHH-16385" )
|
||||
public void testQueryCacheKeyIsImmutable(SessionFactoryScope scope) {
|
||||
scope.getSessionFactory().getCache().evictQueryRegions();
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
session.enableFilter( "personName" ).setParameter( "name", "John" );
|
||||
executeQuery( session, 1 );
|
||||
// cache query key should not be affected by changing enabled filters
|
||||
session.enableFilter( "personName2" ).setParameter( "name", "John2" );
|
||||
} );
|
||||
|
||||
assertThat( statistics.getQueryCacheHitCount() ).isEqualTo( 0 );
|
||||
assertThat( statistics.getQueryCacheMissCount() ).isEqualTo( 1 );
|
||||
assertThat( statistics.getQueryCachePutCount() ).isEqualTo( 1 );
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
session.enableFilter( "personName" ).setParameter( "name", "John" );
|
||||
executeQuery( session, 1 );
|
||||
} );
|
||||
|
||||
assertThat( statistics.getQueryCacheHitCount() ).isEqualTo( 1 );
|
||||
assertThat( statistics.getQueryCacheMissCount() ).isEqualTo( 1 );
|
||||
assertThat( statistics.getQueryCachePutCount() ).isEqualTo( 1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
@Jira( "https://hibernate.atlassian.net/browse/HHH-16617" )
|
||||
public void testQueryCacheDifferentFilterParams(SessionFactoryScope scope) {
|
||||
scope.getSessionFactory().getCache().evictQueryRegions();
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
session.enableFilter( "personName" ).setParameter( "name", "John" );
|
||||
executeQuery( session, 1 );
|
||||
} );
|
||||
|
||||
assertThat( statistics.getQueryCacheHitCount() ).isEqualTo( 0 );
|
||||
assertThat( statistics.getQueryCacheMissCount() ).isEqualTo( 1 );
|
||||
assertThat( statistics.getQueryCachePutCount() ).isEqualTo( 1 );
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
session.enableFilter( "personName" ).setParameter( "name", "Jack" );
|
||||
executeQuery( session, 0 );
|
||||
} );
|
||||
|
||||
assertThat( statistics.getQueryCacheHitCount() ).isEqualTo( 0 );
|
||||
assertThat( statistics.getQueryCacheMissCount() ).isEqualTo( 2 );
|
||||
assertThat( statistics.getQueryCachePutCount() ).isEqualTo( 2 );
|
||||
}
|
||||
|
||||
private void executeQuery(SessionImplementor session, int expectedResults) {
|
||||
final List<Person> resultList = session.createQuery(
|
||||
"from Person p",
|
||||
Person.class
|
||||
).setCacheable( true ).getResultList();
|
||||
assertThat( resultList ).hasSize( expectedResults );
|
||||
}
|
||||
|
||||
@Entity( name = "Person" )
|
||||
@FilterDef( name = "personName", parameters = @ParamDef( name = "name", type = String.class ) )
|
||||
@Filter( name = "personName", condition = "name = :name" )
|
||||
@FilterDef( name = "personName2", parameters = @ParamDef( name = "name", type = String.class ) )
|
||||
@Filter( name = "personName2", condition = "name = :name" )
|
||||
public static class Person {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,10 +13,13 @@ import org.hibernate.stat.CacheRegionStatistics;
|
|||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.Jira;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -27,87 +30,94 @@ import jakarta.persistence.Id;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DomainModel(annotatedClasses = {
|
||||
QueryCacheWithFilterTest.Person.class,
|
||||
})
|
||||
@SessionFactory(generateStatistics = true)
|
||||
@ServiceRegistry(
|
||||
settings = {
|
||||
@Setting(name = AvailableSettings.USE_QUERY_CACHE, value = "true"),
|
||||
@Setting(name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true"),
|
||||
@Setting(name = AvailableSettings.CACHE_REGION_FACTORY, value = "jcache")
|
||||
}
|
||||
)
|
||||
@DomainModel( annotatedClasses = QueryCacheWithFilterTest.Person.class )
|
||||
@SessionFactory( generateStatistics = true )
|
||||
@ServiceRegistry( settings = {
|
||||
@Setting( name = AvailableSettings.USE_QUERY_CACHE, value = "true" ),
|
||||
@Setting( name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true" ),
|
||||
@Setting( name = AvailableSettings.CACHE_REGION_FACTORY, value = "jcache" )
|
||||
} )
|
||||
public class QueryCacheWithFilterTest {
|
||||
|
||||
@BeforeEach
|
||||
@BeforeAll
|
||||
public void setUp(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Person p = new Person();
|
||||
p.setName( "John" );
|
||||
session.persist( p );
|
||||
}
|
||||
);
|
||||
scope.inTransaction( session -> session.persist( new Person( "John" ) ) );
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> session.createMutationQuery( "delete from Person" ).executeUpdate() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryKeyIsSerializable(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.enableFilter( "personName" )
|
||||
.setParameter( "name", "John" );
|
||||
Query<Person> query = session.createQuery(
|
||||
"from Person p",
|
||||
Person.class
|
||||
);
|
||||
query.setCacheable( true );
|
||||
@Jira( "https://hibernate.atlassian.net/browse/HHH-16385" )
|
||||
public void testQueryCacheKeyIsImmutable(SessionFactoryScope scope) {
|
||||
scope.getSessionFactory().getCache().evictQueryRegions();
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
||||
List<Person> resultList1 = query.getResultList();
|
||||
assertThat( resultList1 ).hasSize( 1 );
|
||||
scope.inTransaction( session -> {
|
||||
session.enableFilter( "personName" ).setParameter( "name", "John" );
|
||||
executeQuery( session, 1 );
|
||||
// cache query key should not be affected by changing enabled filters
|
||||
session.enableFilter( "personName2" ).setParameter( "name", "John2" );
|
||||
} );
|
||||
|
||||
//if QueryKey is not serializable, EHCache will silently fail the cache store operation
|
||||
}
|
||||
);
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.enableFilter( "personName" )
|
||||
.setParameter( "name", "John" );
|
||||
Query<Person> query = session.createQuery(
|
||||
"from Person p",
|
||||
Person.class
|
||||
);
|
||||
query.setCacheable( true );
|
||||
assertThat( statistics.getQueryCacheHitCount() ).isEqualTo( 0 );
|
||||
assertThat( statistics.getQueryCacheMissCount() ).isEqualTo( 1 );
|
||||
assertThat( statistics.getQueryCachePutCount() ).isEqualTo( 1 );
|
||||
|
||||
List<Person> resultList = query.getResultList();
|
||||
assertThat( resultList ).hasSize( 1 );
|
||||
scope.inTransaction( session -> {
|
||||
session.enableFilter( "personName" ).setParameter( "name", "John" );
|
||||
executeQuery( session, 1 );
|
||||
} );
|
||||
|
||||
assertThat( getQueryCacheRegionStatistics( session ).getHitCount() ).isEqualTo( 1 );
|
||||
}
|
||||
);
|
||||
assertThat( statistics.getQueryCacheHitCount() ).isEqualTo( 1 );
|
||||
assertThat( statistics.getQueryCacheMissCount() ).isEqualTo( 1 );
|
||||
assertThat( statistics.getQueryCachePutCount() ).isEqualTo( 1 );
|
||||
}
|
||||
|
||||
private static CacheRegionStatistics getQueryCacheRegionStatistics(SessionImplementor session) {
|
||||
StatisticsImplementor statistics = session.getSessionFactory().getStatistics();
|
||||
return statistics.getQueryRegionStatistics( RegionFactory.DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME );
|
||||
@Test
|
||||
@Jira( "https://hibernate.atlassian.net/browse/HHH-16617" )
|
||||
public void testQueryCacheDifferentFilterParams(SessionFactoryScope scope) {
|
||||
scope.getSessionFactory().getCache().evictQueryRegions();
|
||||
final StatisticsImplementor statistics = scope.getSessionFactory().getStatistics();
|
||||
statistics.clear();
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
session.enableFilter( "personName" ).setParameter( "name", "John" );
|
||||
executeQuery( session, 1 );
|
||||
} );
|
||||
|
||||
assertThat( statistics.getQueryCacheHitCount() ).isEqualTo( 0 );
|
||||
assertThat( statistics.getQueryCacheMissCount() ).isEqualTo( 1 );
|
||||
assertThat( statistics.getQueryCachePutCount() ).isEqualTo( 1 );
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
session.enableFilter( "personName" ).setParameter( "name", "Jack" );
|
||||
executeQuery( session, 0 );
|
||||
} );
|
||||
|
||||
assertThat( statistics.getQueryCacheHitCount() ).isEqualTo( 0 );
|
||||
assertThat( statistics.getQueryCacheMissCount() ).isEqualTo( 2 );
|
||||
assertThat( statistics.getQueryCachePutCount() ).isEqualTo( 2 );
|
||||
}
|
||||
|
||||
@Entity(name = "Person")
|
||||
@FilterDef(
|
||||
name = "personName",
|
||||
parameters = @ParamDef(
|
||||
name = "name",
|
||||
type = String.class
|
||||
)
|
||||
)
|
||||
@Filter(
|
||||
name = "personName",
|
||||
condition = "name = :name"
|
||||
)
|
||||
private void executeQuery(SessionImplementor session, int expectedResults) {
|
||||
final List<Person> resultList = session.createQuery(
|
||||
"from Person p",
|
||||
Person.class
|
||||
).setCacheable( true ).getResultList();
|
||||
assertThat( resultList ).hasSize( expectedResults );
|
||||
}
|
||||
|
||||
@Entity( name = "Person" )
|
||||
@FilterDef( name = "personName", parameters = @ParamDef( name = "name", type = String.class ) )
|
||||
@Filter( name = "personName", condition = "name = :name" )
|
||||
@FilterDef( name = "personName2", parameters = @ParamDef( name = "name", type = String.class ) )
|
||||
@Filter( name = "personName2", condition = "name = :name" )
|
||||
public static class Person {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
@ -126,10 +136,5 @@ public class QueryCacheWithFilterTest {
|
|||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue