HHH-17688 Add test for issue
This commit is contained in:
parent
e8793a883b
commit
02fa42d90c
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* 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.mapping.generated.delegate;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
import org.hibernate.annotations.Generated;
|
||||
import org.hibernate.annotations.SourceType;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
import org.hibernate.engine.jdbc.JdbcLogging;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.generator.EventType;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.resource.jdbc.ResourceRegistry;
|
||||
import org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl;
|
||||
|
||||
import org.hibernate.testing.logger.LogInspectionHelper;
|
||||
import org.hibernate.testing.logger.TriggerOnPrefixLogListener;
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.Jira;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
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 org.jboss.logging.Logger;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Inheritance;
|
||||
import jakarta.persistence.InheritanceType;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marco Belladelli
|
||||
*/
|
||||
@DomainModel( annotatedClasses = {
|
||||
MutationDelegateStatementReleaseTest.IdentityOnly.class,
|
||||
MutationDelegateStatementReleaseTest.IdentityAndValues.class,
|
||||
MutationDelegateStatementReleaseTest.BaseEntity.class,
|
||||
MutationDelegateStatementReleaseTest.ChildEntity.class,
|
||||
} )
|
||||
@SessionFactory
|
||||
@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsIdentityColumns.class )
|
||||
@Jira( "https://hibernate.atlassian.net/browse/HHH-17688" )
|
||||
public class MutationDelegateStatementReleaseTest {
|
||||
private TriggerOnPrefixLogListener trigger;
|
||||
|
||||
@BeforeAll
|
||||
public void setUp(SessionFactoryScope scope) {
|
||||
trigger = new TriggerOnPrefixLogListener( Set.of( "Exception clearing", "Unable to release" ) );
|
||||
LogInspectionHelper.registerListener(
|
||||
trigger,
|
||||
Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
ResourceRegistryStandardImpl.class.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void reset() {
|
||||
trigger.reset();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
LogInspectionHelper.clearAllListeners( JdbcLogging.JDBC_MESSAGE_LOGGER );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertGeneratedIdentityOnly(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final IdentityOnly entity = new IdentityOnly();
|
||||
session.persist( entity );
|
||||
session.flush();
|
||||
assertNoOrphanStatements( session );
|
||||
assertThat( entity.getId() ).isNotNull();
|
||||
assertThat( entity.getName() ).isNull();
|
||||
} );
|
||||
|
||||
assertThat( trigger.wasTriggered() ).as( "Exception encountered while releasing statement" ).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertGeneratedValuesAndIdentity(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final IdentityAndValues entity = new IdentityAndValues();
|
||||
session.persist( entity );
|
||||
session.flush();
|
||||
assertNoOrphanStatements( session );
|
||||
assertThat( entity.getId() ).isNotNull();
|
||||
assertThat( entity.getName() ).isEqualTo( "default_name" );
|
||||
} );
|
||||
|
||||
assertThat( trigger.wasTriggered() ).as( "Exception encountered while releasing statement" ).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateGeneratedValuesAndIdentity(SessionFactoryScope scope) {
|
||||
final Long id = scope.fromTransaction( session -> {
|
||||
final IdentityAndValues entity = new IdentityAndValues();
|
||||
session.persist( entity );
|
||||
session.flush();
|
||||
return entity.getId();
|
||||
} );
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
final IdentityAndValues entity = session.find( IdentityAndValues.class, id );
|
||||
entity.setData( "changed" );
|
||||
session.flush();
|
||||
assertNoOrphanStatements( session );
|
||||
assertThat( entity.getUpdateDate() ).isNotNull();
|
||||
} );
|
||||
|
||||
assertThat( trigger.wasTriggered() ).as( "Exception encountered while releasing statement" ).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertChildEntity(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final ChildEntity entity = new ChildEntity();
|
||||
session.persist( entity );
|
||||
session.flush();
|
||||
assertNoOrphanStatements( session );
|
||||
assertThat( entity.getId() ).isNotNull();
|
||||
assertThat( entity.getName() ).isEqualTo( "default_name" );
|
||||
assertThat( entity.getChildName() ).isEqualTo( "default_child_name" );
|
||||
} );
|
||||
|
||||
assertThat( trigger.wasTriggered() ).as( "Exception encountered while releasing update statement" ).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChildEntity(SessionFactoryScope scope) {
|
||||
final Long id = scope.fromTransaction( session -> {
|
||||
final ChildEntity entity = new ChildEntity();
|
||||
session.persist( entity );
|
||||
session.flush();
|
||||
return entity.getId();
|
||||
} );
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
final ChildEntity entity = session.find( ChildEntity.class, id );
|
||||
entity.setData( "changed" );
|
||||
session.flush();
|
||||
assertNoOrphanStatements( session );
|
||||
assertThat( entity.getUpdateDate() ).isNotNull();
|
||||
assertThat( entity.getChildUpdateDate() ).isNotNull();
|
||||
} );
|
||||
|
||||
assertThat( trigger.wasTriggered() ).as( "Exception encountered while releasing update statement" ).isFalse();
|
||||
}
|
||||
|
||||
private void assertNoOrphanStatements(SessionImplementor session) {
|
||||
final ResourceRegistry resourceRegistry = session.getJdbcCoordinator()
|
||||
.getLogicalConnection()
|
||||
.getResourceRegistry();
|
||||
assertThat( resourceRegistry.hasRegisteredResources() ).as( "Expected no registered resources" ).isFalse();
|
||||
}
|
||||
|
||||
@Entity( name = "IdentityOnly" )
|
||||
public static class IdentityOnly {
|
||||
@Id
|
||||
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity( name = "IdentityAndValues" )
|
||||
@SuppressWarnings( "unused" )
|
||||
public static class IdentityAndValues {
|
||||
@Id
|
||||
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
||||
private Long id;
|
||||
|
||||
@Generated( event = EventType.INSERT )
|
||||
@ColumnDefault( "'default_name'" )
|
||||
private String name;
|
||||
|
||||
@UpdateTimestamp( source = SourceType.DB )
|
||||
private Date updateDate;
|
||||
|
||||
private String data;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Date getUpdateDate() {
|
||||
return updateDate;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity( name = "BaseEntity" )
|
||||
@Inheritance( strategy = InheritanceType.JOINED )
|
||||
@SuppressWarnings( "unused" )
|
||||
public static class BaseEntity {
|
||||
@Id
|
||||
@GeneratedValue( strategy = GenerationType.IDENTITY )
|
||||
private Long id;
|
||||
|
||||
@Generated( event = EventType.INSERT )
|
||||
@ColumnDefault( "'default_name'" )
|
||||
private String name;
|
||||
|
||||
@UpdateTimestamp( source = SourceType.DB )
|
||||
private Date updateDate;
|
||||
|
||||
@SuppressWarnings( "FieldCanBeLocal" )
|
||||
private String data;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Date getUpdateDate() {
|
||||
return updateDate;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity( name = "ChildEntity" )
|
||||
@SuppressWarnings( "unused" )
|
||||
public static class ChildEntity extends BaseEntity {
|
||||
@Generated( event = EventType.INSERT )
|
||||
@ColumnDefault( "'default_child_name'" )
|
||||
private String childName;
|
||||
|
||||
@UpdateTimestamp( source = SourceType.DB )
|
||||
private Date childUpdateDate;
|
||||
|
||||
public String getChildName() {
|
||||
return childName;
|
||||
}
|
||||
|
||||
public Date getChildUpdateDate() {
|
||||
return childUpdateDate;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -121,6 +121,9 @@ logger.scanning-coordinator.level=debug
|
|||
logger.abstract-persistent-collection.name=org.hibernate.collection.spi.AbstractPersistentCollection
|
||||
logger.abstract-persistent-collection.level=debug
|
||||
|
||||
logger.resource-registry-standard.name=org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl
|
||||
logger.resource-registry-standard.level=debug
|
||||
|
||||
logger.cache.name=org.hibernate.cache
|
||||
logger.cache.level=trace
|
||||
logger.stat.name=org.hibernate.stat
|
||||
|
|
Loading…
Reference in New Issue