diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/HighlightingFormatter.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/HighlightingFormatter.java index a3fa919603..f75a87a113 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/HighlightingFormatter.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/HighlightingFormatter.java @@ -14,6 +14,8 @@ import java.util.HashSet; import java.util.Set; import java.util.StringTokenizer; +import static org.hibernate.internal.util.StringHelper.isEmpty; + /** * Performs basic syntax highlighting for SQL using ANSI escape codes. * @@ -57,6 +59,10 @@ public final class HighlightingFormatter implements Formatter { @Override public String format(String sql) { + if ( isEmpty( sql ) ) { + return sql; + } + StringBuilder result = new StringBuilder(); boolean inString = false; boolean inQuoted = false; diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java index 30829f46b3..8a1526d548 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java @@ -8,9 +8,11 @@ package org.hibernate.id.insert; import org.hibernate.MappingException; import org.hibernate.boot.model.relational.SqlStringGenerationContext; +import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl; import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.id.PostInsertIdentityPersister; +import org.hibernate.internal.CoreLogging; import org.hibernate.jdbc.Expectation; import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping; import org.hibernate.sql.model.ast.builder.TableInsertBuilder; @@ -63,6 +65,9 @@ public class BasicSelectingDelegate extends AbstractSelectingDelegate { @Override protected String getSelectSQL() { + if ( persister.getIdentitySelectString() == null && !dialect.getIdentityColumnSupport().supportsInsertSelectIdentity() ) { + throw CoreLogging.messageLogger( BasicSelectingDelegate.class ).nullIdentitySelectString(); + } return persister.getIdentitySelectString(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java b/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java index 1051d980fd..f64d20f198 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java @@ -1824,4 +1824,8 @@ public interface CoreMessageLogger extends BasicLogger { id = 514) void postgreSQLJdbcDriverNotAccessible(); + @Message(value = "The identity select string is undefined for the dialect in use. Check the identity generation configuration, in particular the 'hibernate.jdbc.use_get_generated_keys' setting", + id = 515) + HibernateException nullIdentitySelectString(); + } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/IdentityIdEntityTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/IdentityIdEntityTest.java index f189328157..dcc8d2824a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/IdentityIdEntityTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/IdentityIdEntityTest.java @@ -14,6 +14,7 @@ import jakarta.persistence.Id; import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.H2Dialect; +import org.hibernate.dialect.OracleDialect; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.orm.junit.DomainModel; @@ -26,13 +27,12 @@ import org.hibernate.testing.orm.junit.Setting; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; /** * @author Jan Schatteman */ -@TestForIssue(jiraKey = "HHH-15561") -@RequiresDialect( value = H2Dialect.class ) public class IdentityIdEntityTest { @AfterEach @@ -43,11 +43,13 @@ public class IdentityIdEntityTest { } @Test + @TestForIssue(jiraKey = "HHH-15561") @ServiceRegistry( settings = { @Setting( name = AvailableSettings.USE_GET_GENERATED_KEYS, value = "false") } ) @DomainModel( annotatedClasses = { IdentityEntity.class } ) @SessionFactory + @RequiresDialect( value = H2Dialect.class ) public void testIdentityEntityWithDisabledGetGeneratedKeys(SessionFactoryScope scope) { scope.inTransaction( session -> { @@ -64,11 +66,13 @@ public class IdentityIdEntityTest { } @Test + @TestForIssue(jiraKey = "HHH-15561") @ServiceRegistry( settings = { @Setting( name = "use_jdbc_metadata_defaults", value = "false") } ) @DomainModel( annotatedClasses = { IdentityEntity.class } ) @SessionFactory + @RequiresDialect( value = H2Dialect.class ) public void testIdentityEntityWithDisabledJdbcMetadataDefaults(SessionFactoryScope scope) { scope.inTransaction( session -> { @@ -84,6 +88,30 @@ public class IdentityIdEntityTest { ); } + @Test + @TestForIssue(jiraKey = "HHH-16418") + @ServiceRegistry( + settings = { @Setting( name = AvailableSettings.USE_GET_GENERATED_KEYS, value = "false") } + ) + @DomainModel( annotatedClasses = { IdentityEntity.class } ) + @SessionFactory + @RequiresDialect( value = OracleDialect.class, majorVersion = 12 ) + public void testNullSelectIdentityString(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + try { + IdentityEntity ie = new IdentityEntity(); + ie.setTimestamp( new Date() ); + session.persist( ie ); + fail( "A HibernateException with message id HHH000515 should have been thrown" ); + } + catch (Exception e) { + assertTrue( e.getMessage().startsWith( "HHH000515" ) ); + } + } + ); + } + @Entity(name = "id_entity") public static class IdentityEntity { @Id