HHH-15561 - Fixed and added test for issue
Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
parent
f13230803d
commit
0baefce734
|
@ -28,6 +28,7 @@ import org.hibernate.dialect.SimpleDatabaseVersion;
|
|||
import org.hibernate.dialect.TimeZoneSupport;
|
||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||
import org.hibernate.dialect.hint.IndexQueryHintHandler;
|
||||
import org.hibernate.dialect.identity.H2FinalTableIdentityColumnSupport;
|
||||
import org.hibernate.dialect.identity.H2IdentityColumnSupport;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
|
@ -774,7 +775,7 @@ public class H2LegacyDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public IdentityColumnSupport getIdentityColumnSupport() {
|
||||
return new H2IdentityColumnSupport();
|
||||
return getVersion().isSameOrAfter( 2 ) ? H2FinalTableIdentityColumnSupport.INSTANCE : H2IdentityColumnSupport.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.PessimisticLockException;
|
|||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||
import org.hibernate.dialect.hint.IndexQueryHintHandler;
|
||||
import org.hibernate.dialect.identity.H2FinalTableIdentityColumnSupport;
|
||||
import org.hibernate.dialect.identity.H2IdentityColumnSupport;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
|
@ -741,7 +742,7 @@ public class H2Dialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public IdentityColumnSupport getIdentityColumnSupport() {
|
||||
return new H2IdentityColumnSupport();
|
||||
return getVersion().isSameOrAfter( 2 ) ? H2FinalTableIdentityColumnSupport.INSTANCE : H2IdentityColumnSupport.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.dialect.identity;
|
||||
|
||||
/**
|
||||
* Identity column support for H2 2+ versions
|
||||
* @author Jan Schatteman
|
||||
*/
|
||||
public class H2FinalTableIdentityColumnSupport extends H2IdentityColumnSupport {
|
||||
|
||||
public static final H2FinalTableIdentityColumnSupport INSTANCE = new H2FinalTableIdentityColumnSupport();
|
||||
|
||||
private H2FinalTableIdentityColumnSupport() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsInsertSelectIdentity() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String appendIdentitySelectToInsert(String identityColumnName, String insertString) {
|
||||
return "select " + identityColumnName + " from final table ( " + insertString + " )";
|
||||
}
|
||||
}
|
|
@ -10,6 +10,12 @@ package org.hibernate.dialect.identity;
|
|||
* @author Andrea Boriero
|
||||
*/
|
||||
public class H2IdentityColumnSupport extends IdentityColumnSupportImpl {
|
||||
|
||||
public static final H2IdentityColumnSupport INSTANCE = new H2IdentityColumnSupport();
|
||||
|
||||
protected H2IdentityColumnSupport() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
|
|
|
@ -57,6 +57,23 @@ public interface IdentityColumnSupport {
|
|||
*/
|
||||
String appendIdentitySelectToInsert(String insertString);
|
||||
|
||||
/**
|
||||
* Provided we {@link #supportsInsertSelectIdentity}, then attach the
|
||||
* "select identity" clause to the insert statement.
|
||||
* <p/>
|
||||
* Note, if {@link #supportsInsertSelectIdentity} == false then
|
||||
* the insert-string should be returned without modification.
|
||||
*
|
||||
* @param identityColumnName The name of the identity column
|
||||
* @param insertString The insert command
|
||||
*
|
||||
* @return The insert command with any necessary identity select
|
||||
* clause attached.
|
||||
*/
|
||||
default String appendIdentitySelectToInsert(String identityColumnName, String insertString) {
|
||||
return appendIdentitySelectToInsert( insertString );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the select command to use to retrieve the last generated IDENTITY
|
||||
* value for a particular table
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.id.insert;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.sql.Insert;
|
||||
|
||||
/**
|
||||
* Specialized IdentifierGeneratingInsert which appends the database
|
||||
|
@ -15,11 +16,18 @@ import org.hibernate.dialect.Dialect;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class InsertSelectIdentityInsert extends IdentifierGeneratingInsert {
|
||||
protected String identityColumnName;
|
||||
|
||||
public Insert addIdentityColumn(String columnName) {
|
||||
identityColumnName = columnName;
|
||||
return super.addIdentityColumn( columnName );
|
||||
}
|
||||
|
||||
public InsertSelectIdentityInsert(Dialect dialect) {
|
||||
super( dialect );
|
||||
}
|
||||
|
||||
public String toStatementString() {
|
||||
return getDialect().getIdentityColumnSupport().appendIdentitySelectToInsert( super.toStatementString() );
|
||||
return getDialect().getIdentityColumnSupport().appendIdentitySelectToInsert( identityColumnName, super.toStatementString() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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.id;
|
||||
|
||||
import java.util.Date;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||
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.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* @author Jan Schatteman
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-15561")
|
||||
@RequiresDialect( value = H2Dialect.class )
|
||||
public class IdentityIdEntityTest {
|
||||
|
||||
@AfterEach
|
||||
public void cleanup(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> session.createMutationQuery( "delete from id_entity" ).executeUpdate()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ServiceRegistry(
|
||||
settings = { @Setting( name = AvailableSettings.USE_GET_GENERATED_KEYS, value = "false") }
|
||||
)
|
||||
@DomainModel( annotatedClasses = { IdentityEntity.class } )
|
||||
@SessionFactory
|
||||
public void testIdentityEntityWithDisabledGetGeneratedKeys(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
try {
|
||||
IdentityEntity ie = new IdentityEntity();
|
||||
ie.setTimestamp( new Date() );
|
||||
session.persist( ie );
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( "Creation of an IDENTITY-id-based entity failed when \"hibernate.jdbc.use_get_generated_keys\" was set to false (" + e.getMessage() + ")" );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ServiceRegistry(
|
||||
settings = { @Setting( name = "use_jdbc_metadata_defaults", value = "false") }
|
||||
)
|
||||
@DomainModel( annotatedClasses = { IdentityEntity.class } )
|
||||
@SessionFactory
|
||||
public void testIdentityEntityWithDisabledJdbcMetadataDefaults(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
try {
|
||||
IdentityEntity ie = new IdentityEntity();
|
||||
ie.setTimestamp( new Date() );
|
||||
session.persist( ie );
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( "Creation of an IDENTITY-id-based entity failed when \"use_jdbc_metadata_defaults\" was set to false (" + e.getMessage() + ")" );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "id_entity")
|
||||
public static class IdentityEntity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private int id;
|
||||
|
||||
private Date timestamp;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(Date timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue