From 3553576236866fbcdda012852e8ecff9f73bf2bc Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Mon, 6 Jul 2020 15:02:54 +0100 Subject: [PATCH] HHH-13214 Delete re-firing SQL from previous calls --- .../AbstractInlineIdsDeleteHandlerImpl.java | 6 +- .../AbstractInlineIdsUpdateHandlerImpl.java | 3 +- .../InheritanceDeleteBatchTest.java | 115 ++++++++++++++++++ 3 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/inheritance/InheritanceDeleteBatchTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/hql/spi/id/inline/AbstractInlineIdsDeleteHandlerImpl.java b/hibernate-core/src/main/java/org/hibernate/hql/spi/id/inline/AbstractInlineIdsDeleteHandlerImpl.java index 6a60d22acd..db0c796b74 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/spi/id/inline/AbstractInlineIdsDeleteHandlerImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/spi/id/inline/AbstractInlineIdsDeleteHandlerImpl.java @@ -18,6 +18,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.hql.internal.ast.HqlSqlWalker; import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.persister.collection.AbstractCollectionPersister; import org.hibernate.persister.entity.Queryable; import org.hibernate.sql.Delete; @@ -33,7 +34,7 @@ public abstract class AbstractInlineIdsDeleteHandlerImpl extends AbstractInlineIdsBulkIdHandler implements MultiTableBulkIdStrategy.DeleteHandler { - private List deletes; + private List deletes = new ArrayList<>(); public AbstractInlineIdsDeleteHandlerImpl( SessionFactoryImplementor factory, @@ -44,7 +45,7 @@ public abstract class AbstractInlineIdsDeleteHandlerImpl @Override public String[] getSqlStatements() { if ( deletes.isEmpty() ) { - return new String[0]; + return ArrayHelper.EMPTY_STRING_ARRAY; } return deletes.toArray( new String[deletes.size()] ); } @@ -55,7 +56,6 @@ public abstract class AbstractInlineIdsDeleteHandlerImpl QueryParameters queryParameters) { IdsClauseBuilder values = prepareInlineStatement( session, queryParameters ); - deletes = new ArrayList<>(); if ( !values.getIds().isEmpty() ) { final String idSubselect = values.toStatement(); diff --git a/hibernate-core/src/main/java/org/hibernate/hql/spi/id/inline/AbstractInlineIdsUpdateHandlerImpl.java b/hibernate-core/src/main/java/org/hibernate/hql/spi/id/inline/AbstractInlineIdsUpdateHandlerImpl.java index 04acedf428..ca5c5e62a0 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/spi/id/inline/AbstractInlineIdsUpdateHandlerImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/spi/id/inline/AbstractInlineIdsUpdateHandlerImpl.java @@ -22,6 +22,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.hql.internal.ast.HqlSqlWalker; import org.hibernate.hql.internal.ast.tree.AssignmentSpecification; import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.param.ParameterSpecification; import org.hibernate.persister.entity.Queryable; import org.hibernate.sql.Update; @@ -48,7 +49,7 @@ public abstract class AbstractInlineIdsUpdateHandlerImpl @Override public String[] getSqlStatements() { if ( updates == null ) { - return new String[0]; + return ArrayHelper.EMPTY_STRING_ARRAY; } return updates.values().toArray( new String[updates.values().size()] ); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/inheritance/InheritanceDeleteBatchTest.java b/hibernate-core/src/test/java/org/hibernate/test/inheritance/InheritanceDeleteBatchTest.java new file mode 100644 index 0000000000..aa228759e9 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/inheritance/InheritanceDeleteBatchTest.java @@ -0,0 +1,115 @@ +/* + * 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 . + */ +package org.hibernate.test.inheritance; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.Query; +import javax.persistence.Table; + +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.Configuration; +import org.hibernate.hql.spi.id.inline.InlineIdsInClauseBulkIdStrategy; +import org.hibernate.stat.spi.StatisticsImplementor; + +import org.hibernate.testing.DialectChecks; +import org.hibernate.testing.RequiresDialectFeature; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; + +/** + * @author Andrea Boriero + */ +@RequiresDialectFeature(DialectChecks.SupportsRowValueConstructorSyntaxInInListCheck.class) +@TestForIssue(jiraKey = "HHH-13214") +public class InheritanceDeleteBatchTest extends BaseCoreFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + TestEntity.class, + TestEntityType1.class, + TestEntityType2.class + }; + } + + @Override + protected void configure(Configuration configuration) { + configuration.setProperty( + AvailableSettings.HQL_BULK_ID_STRATEGY, + InlineIdsInClauseBulkIdStrategy.class.getName() + ); + configuration.setProperty( AvailableSettings.GENERATE_STATISTICS, "true" ); + } + + @Before + public void setUp() { + doInHibernate( this::sessionFactory, session -> { + session.persist( new TestEntity( 1 ) ); + session.persist( new TestEntityType1( 2 ) ); + session.persist( new TestEntityType2( 3 ) ); + session.persist( new TestEntityType2( 4 ) ); + } ); + } + + @Test + public void testDelete() { + StatisticsImplementor statistics = sessionFactory().getStatistics(); + statistics.clear(); + doInHibernate( this::sessionFactory, session -> { + for ( int i = 1; i <= 4; i++ ) { + Query deleteQuery = session.createQuery( "delete TestEntity e where e.id = :id" ); + deleteQuery.setParameter( "id", i ); + deleteQuery.executeUpdate(); + assertThat( statistics.getPrepareStatementCount(), is( 4L ) ); + statistics.clear(); + } + } ); + } + + @Entity(name = "TestEntity") + @Inheritance(strategy = InheritanceType.JOINED) + @Table(name = "test_entity") + public static class TestEntity { + @Id + int id; + + private String field; + + public TestEntity() { + } + + public TestEntity(int id) { + this.id = id; + } + } + + @Entity(name = "TestEntityType1") + @Table(name = "test_entity_type1") + public static class TestEntityType1 extends TestEntity { + + public TestEntityType1(int id) { + super( id ); + } + } + + @Entity(name = "TestEntityType2") + @Table(name = "test_entity_type2") + public static class TestEntityType2 extends TestEntity { + public TestEntityType2(int id) { + super( id ); + } + } +}