HHH-15150 Add test for issue
This commit is contained in:
parent
5d0fc0f488
commit
1194e7f23b
|
@ -0,0 +1,107 @@
|
||||||
|
package org.hibernate.orm.test.serialization;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
|
||||||
|
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
|
||||||
|
import org.hibernate.cache.internal.SimpleCacheKeysFactory;
|
||||||
|
import org.hibernate.cache.spi.CacheKeysFactory;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.orm.test.serialization.entity.PK;
|
||||||
|
import org.hibernate.orm.test.serialization.entity.WithEmbeddedId;
|
||||||
|
import org.hibernate.orm.test.serialization.entity.WithSimpleId;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.cache.CachingRegionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.BaseUnitTest;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
@BaseUnitTest
|
||||||
|
public class CacheKeySerializationTest {
|
||||||
|
private SessionFactoryImplementor getSessionFactory(String cacheKeysFactory) {
|
||||||
|
Configuration configuration = new Configuration()
|
||||||
|
.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true")
|
||||||
|
.setProperty(Environment.CACHE_REGION_FACTORY, CachingRegionFactory.class.getName())
|
||||||
|
.setProperty(Environment.DEFAULT_CACHE_CONCURRENCY_STRATEGY, "transactional")
|
||||||
|
.setProperty("javax.persistence.sharedCache.mode", "ALL")
|
||||||
|
.setProperty(Environment.HBM2DDL_AUTO, "create-drop");
|
||||||
|
if (cacheKeysFactory != null) {
|
||||||
|
configuration.setProperty(Environment.CACHE_KEYS_FACTORY, cacheKeysFactory);
|
||||||
|
}
|
||||||
|
configuration.addAnnotatedClass( WithSimpleId.class );
|
||||||
|
configuration.addAnnotatedClass( WithEmbeddedId.class );
|
||||||
|
return (SessionFactoryImplementor) configuration.buildSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-11202")
|
||||||
|
public void testSimpleCacheKeySimpleId() throws Exception {
|
||||||
|
testId( SimpleCacheKeysFactory.INSTANCE, WithSimpleId.class.getName(), 1L );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-11202")
|
||||||
|
public void testSimpleCacheKeyEmbeddedId() throws Exception {
|
||||||
|
testId( SimpleCacheKeysFactory.INSTANCE, WithEmbeddedId.class.getName(), new PK( 1L ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-11202")
|
||||||
|
public void testDefaultCacheKeySimpleId() throws Exception {
|
||||||
|
testId( DefaultCacheKeysFactory.INSTANCE, WithSimpleId.class.getName(), 1L );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-11202")
|
||||||
|
public void testDefaultCacheKeyEmbeddedId() throws Exception {
|
||||||
|
testId( DefaultCacheKeysFactory.INSTANCE, WithEmbeddedId.class.getName(), new PK( 1L ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testId(CacheKeysFactory cacheKeysFactory, String entityName, Object id) throws Exception {
|
||||||
|
final SessionFactoryImplementor sessionFactory = getSessionFactory(cacheKeysFactory.getClass().getName());
|
||||||
|
final EntityPersister persister = sessionFactory.getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(entityName);
|
||||||
|
final Object key = cacheKeysFactory.createEntityKey(
|
||||||
|
id,
|
||||||
|
persister,
|
||||||
|
sessionFactory,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
final ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||||
|
oos.writeObject( key );
|
||||||
|
|
||||||
|
final ObjectInputStream ois = new ObjectInputStream( new ByteArrayInputStream( baos.toByteArray() ) );
|
||||||
|
final Object keyClone = ois.readObject();
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertEquals( key, keyClone );
|
||||||
|
assertEquals( keyClone, key );
|
||||||
|
|
||||||
|
assertEquals( key.hashCode(), keyClone.hashCode() );
|
||||||
|
|
||||||
|
final Object idClone = cacheKeysFactory.getEntityId( keyClone );
|
||||||
|
|
||||||
|
assertEquals( id.hashCode(), idClone.hashCode() );
|
||||||
|
assertEquals( id, idClone );
|
||||||
|
assertEquals( idClone, id );
|
||||||
|
assertTrue( persister.getIdentifierType().isEqual( id, idClone, sessionFactory ) );
|
||||||
|
assertTrue( persister.getIdentifierType().isEqual( idClone, id, sessionFactory ) );
|
||||||
|
sessionFactory.close();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
sessionFactory.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,9 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.serialization.entity;
|
package org.hibernate.orm.test.serialization.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class should be in a package that is different from the test
|
* This class should be in a package that is different from the test
|
||||||
* so that the test and entity that uses this class for its primary
|
* so that the test and entity that uses this class for its primary
|
||||||
|
@ -13,21 +16,38 @@ package org.hibernate.orm.test.serialization.entity;
|
||||||
*
|
*
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
public class PK {
|
public class PK implements Serializable {
|
||||||
private Long value;
|
private Long id;
|
||||||
|
|
||||||
public PK() {
|
public PK() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PK(Long value) {
|
public PK(Long id) {
|
||||||
this.value = value;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Long getValue() {
|
public Long getId() {
|
||||||
return value;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setValue(Long value) {
|
public void setId(Long id) {
|
||||||
this.value = value;
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( o == null || getClass() != o.getClass() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PK pk = (PK) o;
|
||||||
|
return Objects.equals( id, pk.id );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash( id );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* 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.serialization.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.Cacheable;
|
||||||
|
import jakarta.persistence.EmbeddedId;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class should be in a package that is different from the test
|
||||||
|
* so that the test does not have access to the private embedded ID.
|
||||||
|
*
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Cacheable
|
||||||
|
public class WithEmbeddedId {
|
||||||
|
@EmbeddedId
|
||||||
|
private PK embeddedId;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.hibernate.orm.test.serialization.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.Cacheable;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class should be in a package that is different from the test
|
||||||
|
* so that the test does not have access to the private ID field.
|
||||||
|
*
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Cacheable
|
||||||
|
public class WithSimpleId {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
}
|
|
@ -6,6 +6,11 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.jcache;
|
package org.hibernate.orm.test.jcache;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import jakarta.persistence.Embeddable;
|
||||||
|
import jakarta.persistence.EmbeddedId;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.GeneratedValue;
|
import jakarta.persistence.GeneratedValue;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
|
@ -52,6 +57,7 @@ public class InsertedDataTest {
|
||||||
|
|
||||||
final Metadata metadata = new MetadataSources( serviceRegistry )
|
final Metadata metadata = new MetadataSources( serviceRegistry )
|
||||||
.addAnnotatedClass( CacheableItem.class )
|
.addAnnotatedClass( CacheableItem.class )
|
||||||
|
.addAnnotatedClass( CacheableEmbeddedIdItem.class )
|
||||||
.buildMetadata();
|
.buildMetadata();
|
||||||
TestHelper.createRegions( metadata, true, false );
|
TestHelper.createRegions( metadata, true, false );
|
||||||
|
|
||||||
|
@ -60,6 +66,13 @@ public class InsertedDataTest {
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void releaseResources() {
|
public void releaseResources() {
|
||||||
|
inTransaction(
|
||||||
|
sessionFactory,
|
||||||
|
s -> {
|
||||||
|
s.createQuery( "delete CacheableItem" ).executeUpdate();
|
||||||
|
s.createQuery( "delete from CacheableEmbeddedIdItem" ).executeUpdate();
|
||||||
|
}
|
||||||
|
);
|
||||||
if ( sessionFactory != null ) {
|
if ( sessionFactory != null ) {
|
||||||
sessionFactory.close();
|
sessionFactory.close();
|
||||||
}
|
}
|
||||||
|
@ -84,10 +97,22 @@ public class InsertedDataTest {
|
||||||
|
|
||||||
assertTrue( sessionFactory().getCache().containsEntity( CacheableItem.class, 1L ) );
|
assertTrue( sessionFactory().getCache().containsEntity( CacheableItem.class, 1L ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsert2() {
|
||||||
|
sessionFactory().getCache().evictEntityData();
|
||||||
|
sessionFactory().getStatistics().clear();
|
||||||
|
|
||||||
inTransaction(
|
inTransaction(
|
||||||
sessionFactory,
|
sessionFactory,
|
||||||
s -> s.createQuery( "delete CacheableItem" ).executeUpdate()
|
s -> {
|
||||||
|
CacheableEmbeddedIdItem item = new CacheableEmbeddedIdItem( new PK( 2l ), "data" );
|
||||||
|
s.save( item );
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assertTrue( sessionFactory().getCache().containsEntity( CacheableEmbeddedIdItem.class, new PK( 2l ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -125,10 +150,6 @@ public class InsertedDataTest {
|
||||||
|
|
||||||
assertTrue( sessionFactory().getCache().containsEntity( CacheableItem.class, 1L ) );
|
assertTrue( sessionFactory().getCache().containsEntity( CacheableItem.class, 1L ) );
|
||||||
|
|
||||||
inTransaction(
|
|
||||||
sessionFactory,
|
|
||||||
s -> s.createQuery( "delete CacheableItem" ).executeUpdate()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -167,10 +188,6 @@ public class InsertedDataTest {
|
||||||
|
|
||||||
assertTrue( sessionFactory().getCache().containsEntity( CacheableItem.class, 1L ) );
|
assertTrue( sessionFactory().getCache().containsEntity( CacheableItem.class, 1L ) );
|
||||||
|
|
||||||
inTransaction(
|
|
||||||
sessionFactory,
|
|
||||||
s -> s.createQuery( "delete CacheableItem" ).executeUpdate()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -233,11 +250,24 @@ public class InsertedDataTest {
|
||||||
);
|
);
|
||||||
|
|
||||||
assertTrue( sessionFactory().getCache().containsEntity( CacheableItem.class, 1L ) );
|
assertTrue( sessionFactory().getCache().containsEntity( CacheableItem.class, 1L ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsertWithClear2() {
|
||||||
|
sessionFactory().getCache().evictEntityData();
|
||||||
|
sessionFactory().getStatistics().clear();
|
||||||
|
|
||||||
inTransaction(
|
inTransaction(
|
||||||
sessionFactory,
|
sessionFactory,
|
||||||
s -> s.createQuery( "delete CacheableItem" ).executeUpdate()
|
s -> {
|
||||||
|
CacheableEmbeddedIdItem item = new CacheableEmbeddedIdItem( new PK( 2l ), "data" );
|
||||||
|
s.save( item );
|
||||||
|
s.flush();
|
||||||
|
s.clear();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assertTrue( sessionFactory().getCache().containsEntity( CacheableEmbeddedIdItem.class, new PK( 2l ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -268,6 +298,34 @@ public class InsertedDataTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsertWithClearThenRollback2() {
|
||||||
|
sessionFactory().getCache().evictEntityData();
|
||||||
|
sessionFactory().getStatistics().clear();
|
||||||
|
|
||||||
|
inTransaction(
|
||||||
|
sessionFactory,
|
||||||
|
s -> {
|
||||||
|
CacheableEmbeddedIdItem item = new CacheableEmbeddedIdItem( new PK( 2l ), "data" );
|
||||||
|
s.save( item );
|
||||||
|
s.flush();
|
||||||
|
s.clear();
|
||||||
|
item = s.get( CacheableEmbeddedIdItem.class, item.getId() );
|
||||||
|
s.getTransaction().markRollbackOnly();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assertFalse( sessionFactory().getCache().containsEntity( CacheableEmbeddedIdItem.class, new PK( 2l ) ) );
|
||||||
|
|
||||||
|
inTransaction(
|
||||||
|
sessionFactory,
|
||||||
|
s -> {
|
||||||
|
final CacheableEmbeddedIdItem item = s.get( CacheableEmbeddedIdItem.class, new PK( 2l ) );
|
||||||
|
assertNull( item, "it should be null" );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Entity(name = "CacheableItem")
|
@Entity(name = "CacheableItem")
|
||||||
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "item")
|
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "item")
|
||||||
public static class CacheableItem {
|
public static class CacheableItem {
|
||||||
|
@ -299,4 +357,73 @@ public class InsertedDataTest {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Entity(name = "CacheableEmbeddedIdItem")
|
||||||
|
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "item")
|
||||||
|
public static class CacheableEmbeddedIdItem {
|
||||||
|
private PK id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public CacheableEmbeddedIdItem() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CacheableEmbeddedIdItem(PK id,String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EmbeddedId
|
||||||
|
public PK getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(PK id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class PK implements Serializable {
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
public PK() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public PK(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( o == null || getClass() != o.getClass() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PK pk = (PK) o;
|
||||||
|
return Objects.equals( id, pk.id );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash( id );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue