diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index dee04d4063bd..b091bc81a94f 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -4819,10 +4819,11 @@ private boolean isSubselect() { private boolean generatorNeedsMultiTableInsert() { final var generator = getGenerator(); - if ( generator instanceof BulkInsertionCapableIdentifierGenerator + if ( generator instanceof BulkInsertionCapableIdentifierGenerator bulkInsertionCapableGenerator && generator instanceof OptimizableGenerator optimizableGenerator ) { final var optimizer = optimizableGenerator.getOptimizer(); - return optimizer != null && optimizer.getIncrementSize() > 1; + return optimizer != null && optimizer.getIncrementSize() > 1 + || !bulkInsertionCapableGenerator.supportsBulkInsertionIdentifierGeneration(); } else { return false; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmQueryImpl.java index 80751516bee5..f7e2b839359a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmQueryImpl.java @@ -625,10 +625,11 @@ private boolean useMultiTableInsert(EntityPersister persister, SqmInsertStatemen boolean useMultiTableInsert = persister.hasMultipleTables(); if ( !useMultiTableInsert && !isSimpleValuesInsert( sqmInsert, persister ) ) { final var identifierGenerator = persister.getGenerator(); - if ( identifierGenerator instanceof BulkInsertionCapableIdentifierGenerator + if ( identifierGenerator instanceof BulkInsertionCapableIdentifierGenerator bulkInsertionCapableGenerator && identifierGenerator instanceof OptimizableGenerator optimizableGenerator ) { final var optimizer = optimizableGenerator.getOptimizer(); - if ( optimizer != null && optimizer.getIncrementSize() > 1 ) { + if ( optimizer != null && optimizer.getIncrementSize() > 1 + || !bulkInsertionCapableGenerator.supportsBulkInsertionIdentifierGeneration() ) { useMultiTableInsert = !hasIdentifierAssigned( sqmInsert, persister ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertSelectLegacyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertSelectLegacyTest.java new file mode 100644 index 000000000000..d3e58a0233ba --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertSelectLegacyTest.java @@ -0,0 +1,82 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.query.hql; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.id.enhanced.LegacyNamingStrategy; +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 org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@DomainModel( + annotatedClasses = { + InsertSelectLegacyTest.Person.class, + InsertSelectLegacyTest.Document.class + } +) +@ServiceRegistry( + settings = { + @Setting(name = AvailableSettings.SHOW_SQL, value = "true"), + @Setting(name = AvailableSettings.FORMAT_SQL, value = "true"), + @Setting(name = AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY, + value = LegacyNamingStrategy.STRATEGY_NAME) + } +) +@SessionFactory +public class InsertSelectLegacyTest { + + @Test + @JiraKey(value = "HHH-18835") + void testInsertSelect(SessionFactoryScope scope) { + + scope.inTransaction( session -> { + Person person = new Person(); + person.name = "Peter"; + session.persist( person ); + + session.createMutationQuery( + "insert into Document(name,owner) select concat(p.name,'s document'), p from Person p" ) + .executeUpdate(); + + Document document = session.createQuery( "select d from Document d", Document.class ).getSingleResult(); + assertNotNull( document ); + assertEquals( "Peters document", document.name ); + } ); + } + + @Entity(name = "Person") + public static class Person { + + @Id + @GeneratedValue + Long id; + + String name; + } + + @Entity(name = "Document") + public static class Document { + + @Id + @GeneratedValue + Long id; + + String name; + + @ManyToOne + Person owner; + } +}