HHH-18872 Rename and cleanup test
This commit is contained in:
parent
107e426f0f
commit
3cfa7c7b00
|
@ -1,128 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
* Copyright Red Hat Inc. and Hibernate Authors
|
|
||||||
*/
|
|
||||||
package org.hibernate.orm.test.proxy.concrete;
|
|
||||||
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.Cacheable;
|
|
||||||
import jakarta.persistence.DiscriminatorColumn;
|
|
||||||
import jakarta.persistence.DiscriminatorType;
|
|
||||||
import jakarta.persistence.DiscriminatorValue;
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.Inheritance;
|
|
||||||
import jakarta.persistence.InheritanceType;
|
|
||||||
import jakarta.persistence.JoinColumn;
|
|
||||||
import jakarta.persistence.ManyToOne;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
|
|
||||||
|
|
||||||
import org.hibernate.annotations.Cache;
|
|
||||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
|
||||||
import org.hibernate.annotations.ConcreteProxy;
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
|
||||||
|
|
||||||
import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced;
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
|
||||||
import org.hibernate.testing.orm.junit.JiraKey;
|
|
||||||
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 static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Guillaume Toison
|
|
||||||
*/
|
|
||||||
@JiraKey( "HHH-18872" )
|
|
||||||
@DomainModel(
|
|
||||||
annotatedClasses = {
|
|
||||||
ConcreteProxyCacheTest.TestNode.class, ConcreteProxyCacheTest.TestCompositeNode.class
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@ServiceRegistry(
|
|
||||||
settings = {
|
|
||||||
@Setting( name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true" ),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@SessionFactory
|
|
||||||
@BytecodeEnhanced
|
|
||||||
public class ConcreteProxyCacheTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testManyToOne2LcLoadOfConcreteProxy(SessionFactoryScope scope) throws Exception {
|
|
||||||
scope.inTransaction( s -> {
|
|
||||||
TestCompositeNode node1 = new TestCompositeNode( 1 );
|
|
||||||
TestCompositeNode node2 = new TestCompositeNode( 2 );
|
|
||||||
node1.setParent( node2 );
|
|
||||||
|
|
||||||
s.persist( node1 );
|
|
||||||
s.persist( node2 );
|
|
||||||
} );
|
|
||||||
|
|
||||||
scope.inSession( s -> {
|
|
||||||
// Test the case when node1 is retrieved from 2LC but node2 is not in cache
|
|
||||||
// Hibernate would either need to hit the database to retrieve the type or to the store the type in node1's cache entry
|
|
||||||
s.getSessionFactory().getCache().evict( TestCompositeNode.class, 2 );
|
|
||||||
|
|
||||||
TestCompositeNode node1 = s.getReference( TestCompositeNode.class, 1 );
|
|
||||||
assertTrue( node1.getParent() instanceof TestCompositeNode , "Expecting object to be an instance of TestCompositeNode but the class was " + node1.getParent().getClass() );
|
|
||||||
} );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "node")
|
|
||||||
@Cacheable
|
|
||||||
@ConcreteProxy
|
|
||||||
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
|
||||||
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
|
||||||
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "type")
|
|
||||||
@DiscriminatorValue(value = "SIMPLE")
|
|
||||||
public static class TestNode {
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
public TestNode() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestNode(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Id
|
|
||||||
public Integer getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@DiscriminatorValue("COMPOSITE")
|
|
||||||
public static class TestCompositeNode extends TestNode {
|
|
||||||
private TestNode parent;
|
|
||||||
|
|
||||||
public TestCompositeNode() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestCompositeNode(Integer id) {
|
|
||||||
super(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "parent_id")
|
|
||||||
public TestNode getParent() {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParent(TestNode parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.proxy.concrete;
|
||||||
|
|
||||||
|
import jakarta.persistence.Cacheable;
|
||||||
|
import jakarta.persistence.DiscriminatorColumn;
|
||||||
|
import jakarta.persistence.DiscriminatorType;
|
||||||
|
import jakarta.persistence.DiscriminatorValue;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Inheritance;
|
||||||
|
import jakarta.persistence.InheritanceType;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
|
import org.hibernate.annotations.Cache;
|
||||||
|
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||||
|
import org.hibernate.annotations.ConcreteProxy;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.stat.Statistics;
|
||||||
|
import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@DomainModel(annotatedClasses = {
|
||||||
|
ConcreteProxyToOneSecondLevelCacheTest.TestNode.class,
|
||||||
|
ConcreteProxyToOneSecondLevelCacheTest.TestCompositeNode.class
|
||||||
|
})
|
||||||
|
@ServiceRegistry(settings = {
|
||||||
|
@Setting(name = AvailableSettings.GENERATE_STATISTICS, value = "true"),
|
||||||
|
@Setting(name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true")
|
||||||
|
})
|
||||||
|
@SessionFactory
|
||||||
|
@BytecodeEnhanced(runNotEnhancedAsWell = true)
|
||||||
|
@Jira("https://hibernate.atlassian.net/browse/HHH-18872")
|
||||||
|
public class ConcreteProxyToOneSecondLevelCacheTest {
|
||||||
|
@Test
|
||||||
|
public void testToOneInCacheGetReference(SessionFactoryScope scope) {
|
||||||
|
final Statistics stats = scope.getSessionFactory().getStatistics();
|
||||||
|
stats.clear();
|
||||||
|
// load only the node with ID 1 into the 2LC
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
assertThat( session.find( TestCompositeNode.class, 1 ) ).isNotNull();
|
||||||
|
assertThat( session.find( TestCompositeNode.class, 2 ) ).isNotNull();
|
||||||
|
} );
|
||||||
|
assertCacheStats( stats, 0, 2, 2 );
|
||||||
|
scope.inSession( session -> {
|
||||||
|
final TestCompositeNode node1 = session.getReference( TestCompositeNode.class, 1 );
|
||||||
|
assertThat( Hibernate.isInitialized( node1 ) ).isFalse();
|
||||||
|
// this triggers node1 initialization, but should maintain laziness for parent
|
||||||
|
final TestNode parent = node1.getParent();
|
||||||
|
assertThat( Hibernate.isInitialized( node1 ) ).isTrue();
|
||||||
|
// node 1 will be loaded from cache
|
||||||
|
assertCacheStats( stats, 1, 2, 2 );
|
||||||
|
assertParent( parent, stats, 2 );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToOneNotInCacheGetReference(SessionFactoryScope scope) {
|
||||||
|
final Statistics stats = scope.getSessionFactory().getStatistics();
|
||||||
|
stats.clear();
|
||||||
|
// load only the node with ID 1 into the 2LC
|
||||||
|
scope.inTransaction( session -> assertThat( session.find( TestCompositeNode.class, 1 ) ).isNotNull() );
|
||||||
|
assertCacheStats( stats, 0, 1, 1 );
|
||||||
|
scope.inSession( session -> {
|
||||||
|
final TestCompositeNode node1 = session.getReference( TestCompositeNode.class, 1 );
|
||||||
|
assertThat( Hibernate.isInitialized( node1 ) ).isFalse();
|
||||||
|
// this triggers node1 initialization, but should maintain laziness for parent
|
||||||
|
final TestNode parent = node1.getParent();
|
||||||
|
assertThat( Hibernate.isInitialized( node1 ) ).isTrue();
|
||||||
|
// node 1 will be loaded from cache
|
||||||
|
assertCacheStats( stats, 1, 1, 1 );
|
||||||
|
assertParent( parent, stats, 1 );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToOneInCacheFind(SessionFactoryScope scope) {
|
||||||
|
final Statistics stats = scope.getSessionFactory().getStatistics();
|
||||||
|
stats.clear();
|
||||||
|
// load only the node with ID 1 into the 2LC
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
assertThat( session.find( TestCompositeNode.class, 1 ) ).isNotNull();
|
||||||
|
assertThat( session.find( TestCompositeNode.class, 2 ) ).isNotNull();
|
||||||
|
} );
|
||||||
|
assertCacheStats( stats, 0, 2, 2 );
|
||||||
|
scope.inSession( session -> {
|
||||||
|
final TestCompositeNode node1 = session.find( TestCompositeNode.class, 1 );
|
||||||
|
assertThat( Hibernate.isInitialized( node1 ) ).isTrue();
|
||||||
|
// node 1 will be loaded from cache
|
||||||
|
assertCacheStats( stats, 1, 2, 2 );
|
||||||
|
assertParent( node1.getParent(), stats, 2 );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToOneNotInCacheFind(SessionFactoryScope scope) {
|
||||||
|
final Statistics stats = scope.getSessionFactory().getStatistics();
|
||||||
|
stats.clear();
|
||||||
|
// load only the node with ID 1 into the 2LC
|
||||||
|
scope.inTransaction( session -> assertThat( session.find( TestCompositeNode.class, 1 ) ).isNotNull() );
|
||||||
|
assertCacheStats( stats, 0, 1, 1 );
|
||||||
|
scope.inSession( session -> {
|
||||||
|
final TestCompositeNode node1 = session.find( TestCompositeNode.class, 1 );
|
||||||
|
assertThat( Hibernate.isInitialized( node1 ) ).isTrue();
|
||||||
|
// node 1 will be loaded from cache
|
||||||
|
assertCacheStats( stats, 1, 1, 1 );
|
||||||
|
assertParent( node1.getParent(), stats, 1 );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertParent(final TestNode parent, final Statistics stats, final long hits) {
|
||||||
|
assertThat( TestCompositeNode.class ).as( "Expecting parent proxy to be narrowed to concrete type" )
|
||||||
|
.isAssignableFrom( parent.getClass() );
|
||||||
|
final TestCompositeNode parentComposite = (TestCompositeNode) parent;
|
||||||
|
assertThat( Hibernate.isInitialized( parentComposite ) ).isFalse();
|
||||||
|
assertThat( parentComposite.getName() ).isEqualTo( "parent_node" );
|
||||||
|
assertThat( Hibernate.isInitialized( parentComposite ) ).isTrue();
|
||||||
|
// node 2 will not be found in cache
|
||||||
|
assertCacheStats( stats, hits, 2, 2 );
|
||||||
|
assertThat( parentComposite ).as( String.format(
|
||||||
|
"Expecting parent to be an instance of TestCompositeNode but was: [%s]",
|
||||||
|
parent.getClass()
|
||||||
|
) ).isInstanceOf( TestCompositeNode.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertCacheStats(final Statistics stats, final long hits, final long misses, final long puts) {
|
||||||
|
assertThat( stats.getSecondLevelCacheHitCount() ).isEqualTo( hits );
|
||||||
|
assertThat( stats.getSecondLevelCacheMissCount() ).isEqualTo( misses );
|
||||||
|
assertThat( stats.getSecondLevelCachePutCount() ).isEqualTo( puts );
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void clearCache(SessionFactoryScope scope) {
|
||||||
|
scope.getSessionFactory().getCache().evictAllRegions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public void setUp(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
final TestCompositeNode node1 = new TestCompositeNode( 1, "child_node" );
|
||||||
|
final TestCompositeNode node2 = new TestCompositeNode( 2, "parent_node" );
|
||||||
|
node1.setParent( node2 );
|
||||||
|
session.persist( node1 );
|
||||||
|
session.persist( node2 );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
public void tearDown(SessionFactoryScope scope) {
|
||||||
|
scope.getSessionFactory().getSchemaManager().truncateMappedObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "TestNode")
|
||||||
|
@Cacheable
|
||||||
|
@ConcreteProxy
|
||||||
|
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||||
|
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||||
|
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "disc_col")
|
||||||
|
@DiscriminatorValue(value = "simple")
|
||||||
|
public static class TestNode {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public TestNode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestNode(Integer id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@DiscriminatorValue("composite")
|
||||||
|
public static class TestCompositeNode extends TestNode {
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "parent_id")
|
||||||
|
private TestNode parent;
|
||||||
|
|
||||||
|
public TestCompositeNode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestCompositeNode(Integer id, String name) {
|
||||||
|
super( id, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestNode getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParent(TestNode parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue