HHH-17472 Move `allowAssignedIdentifiers()` up to `Generator` interface

Also test with `@IdGeneratorType`
This commit is contained in:
Marco Belladelli 2024-03-21 15:21:01 +01:00
parent 1e95a8a567
commit 415a27434f
4 changed files with 69 additions and 26 deletions

View File

@ -132,6 +132,20 @@ public interface Generator extends Serializable {
*/ */
EnumSet<EventType> getEventTypes(); EnumSet<EventType> getEventTypes();
/**
* Determine if this generator allows identifier values to be manually assigned to the entity
* instance before persisting it. This is useful when, for example, needing existing assigned
* values to be used as identifiers and falling back to generated values by default.
*
* @return {@code true} if this generator allows pre-assigned identifier values,
* {@code false} otherwise (default).
*
* @since 6.5
*/
default boolean allowAssignedIdentifiers() {
return false;
}
default boolean generatesSometimes() { default boolean generatesSometimes() {
return !getEventTypes().isEmpty(); return !getEventTypes().isEmpty();
} }

View File

@ -155,20 +155,6 @@ public interface IdentifierGenerator extends BeforeExecutionGenerator, Exportabl
return INSERT_ONLY; return INSERT_ONLY;
} }
/**
* Determine if this generator allows identifier values to be manually assigned to the entity
* instance before persisting it. This is useful when, for example, needing existing assigned
* values to be used as identifiers and falling back to generated values by default.
*
* @return {@code true} if this generator allows pre-assigned identifier values,
* {@code false} otherwise (default).
*
* @since 6.5
*/
default boolean allowAssignedIdentifiers() {
return false;
}
/** /**
* Check if JDBC batch inserts are supported. * Check if JDBC batch inserts are supported.
* *

View File

@ -469,9 +469,9 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
if ( generator instanceof IdentifierGenerator ) { if ( generator instanceof IdentifierGenerator ) {
final IdentifierGenerator identifierGenerator = (IdentifierGenerator) generator; final IdentifierGenerator identifierGenerator = (IdentifierGenerator) generator;
identifierGenerator.initialize( sqlStringGenerationContext ); identifierGenerator.initialize( sqlStringGenerationContext );
if ( identifierGenerator.allowAssignedIdentifiers() ) { }
( (SimpleValue) model.getIdentifier() ).setNullValue( "undefined" ); if ( generator.allowAssignedIdentifiers() ) {
} ( (SimpleValue) model.getIdentifier() ).setNullValue( "undefined" );
} }
generators.put( model.getEntityName(), generator ); generators.put( model.getEntityName(), generator );
} ); } );

View File

@ -6,9 +6,17 @@
*/ */
package org.hibernate.orm.test.idgen.userdefined; package org.hibernate.orm.test.idgen.userdefined;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.EnumSet;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.IdGeneratorType;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.BeforeExecutionGenerator;
import org.hibernate.generator.EventType;
import org.hibernate.generator.EventTypeSets;
import org.hibernate.id.enhanced.SequenceStyleGenerator; import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.testing.jdbc.SQLStatementInspector; import org.hibernate.testing.jdbc.SQLStatementInspector;
@ -16,6 +24,7 @@ import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
@ -23,6 +32,9 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.Version; import jakarta.persistence.Version;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
@ -212,12 +224,9 @@ public class SequenceOrAssignedGeneratorTest {
} }
@Entity( name = "MyVersionedEntity" ) @Entity( name = "MyVersionedEntity" )
@GenericGenerator( type = SequenceOrAssignedGenerator.class, name = MyVersionedEntity.SEQUENCE )
public static class MyVersionedEntity { public static class MyVersionedEntity {
protected static final String SEQUENCE = "SEQ_MyVersionedEntity";
@Id @Id
@GeneratedValue( generator = SEQUENCE ) @AssignedOrConstant
private Long id; private Long id;
@Version @Version
@ -252,17 +261,51 @@ public class SequenceOrAssignedGeneratorTest {
if ( owner instanceof MyEntity ) { if ( owner instanceof MyEntity ) {
id = ( (MyEntity) owner ).getId(); id = ( (MyEntity) owner ).getId();
} }
else if ( owner instanceof MyVersionedEntity ) { else {
id = null;
}
return id != null ? id : super.generate( session, owner );
}
@Override
public boolean allowAssignedIdentifiers() {
return true;
}
}
@IdGeneratorType( AssignedOrCountGenerator.class )
@Target( { METHOD, FIELD } )
@Retention( RUNTIME )
public @interface AssignedOrConstant {
}
public static class AssignedOrCountGenerator implements BeforeExecutionGenerator {
private Long count;
public AssignedOrCountGenerator() {
this.count = 1L;
}
@Override
public Object generate(
SharedSessionContractImplementor session,
Object owner,
Object currentValue,
EventType eventType) {
final Long id;
if ( owner instanceof MyVersionedEntity ) {
id = ( (MyVersionedEntity) owner ).getId(); id = ( (MyVersionedEntity) owner ).getId();
} }
else { else {
id = null; id = null;
} }
if ( id != null ) { return id != null ? id : count++;
return id; }
}
return super.generate( session, owner ); @Override
public EnumSet<EventType> getEventTypes() {
return EventTypeSets.INSERT_ONLY;
} }
@Override @Override