HHH-18854 Allow changes to the id generator

Hibernate Reactive needs to replace or extends the original
id generators.

This changes make it possible to pass a function to the EntityMetamodel
that allows Hibernate Reactive to replace the original id generators
This commit is contained in:
Davide D'Alto 2024-11-15 18:14:06 +01:00
parent 65f785c512
commit e0d47306ef
No known key found for this signature in database
GPG Key ID: 163581B9C6E9FC17
6 changed files with 89 additions and 6 deletions

View File

@ -111,6 +111,13 @@ public class TableStructure implements DatabaseStructure {
return physicalTableName;
}
/*
* Used by Hibernate Reactive
*/
public Identifier getLogicalValueColumnNameIdentifier() {
return logicalValueColumnNameIdentifier;
}
@Override
public int getInitialValue() {
return initialValue;

View File

@ -469,11 +469,38 @@ public abstract class AbstractEntityPersister
private List<UniqueKeyEntry> uniqueKeyEntries = null; //lazily initialized
private ConcurrentHashMap<String,SingleIdArrayLoadPlan> nonLazyPropertyLoadPlansByName;
/**
* A factory for the creation of an EntityMetamodel.
* <p>
* Hibernate Reactive uses it to pass its own entity metamodel class
* and adapt the identifier generators.
*/
public static class EntityMetamodelFactory {
public EntityMetamodel createEntityMetamodel(
PersistentClass persistentClass,
EntityPersister persister,
RuntimeModelCreationContext creationContext) {
return new EntityMetamodel( persistentClass, persister, creationContext );
}
}
public AbstractEntityPersister(
final PersistentClass persistentClass,
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext) throws HibernateException {
this( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext, new EntityMetamodelFactory() );
}
/*
* Used by Hibernate Reactive
*/
public AbstractEntityPersister(
final PersistentClass persistentClass,
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext,
final EntityMetamodelFactory entityMetamodelFactory) throws HibernateException {
this.jpaEntityName = persistentClass.getJpaEntityName();
//set it here, but don't call it, since it's still uninitialized!
@ -500,7 +527,7 @@ public abstract class AbstractEntityPersister
isLazyPropertiesCacheable = true;
}
entityMetamodel = new EntityMetamodel( persistentClass, this, creationContext );
entityMetamodel = entityMetamodelFactory.createEntityMetamodel( persistentClass, this, creationContext );
entityEntryFactory = entityMetamodel.isMutable()
? MutableEntityEntryFactory.INSTANCE

View File

@ -160,8 +160,20 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext) throws HibernateException {
this( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext, new EntityMetamodelFactory());
}
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
/*
* Used by Hibernate Reactive
*/
public JoinedSubclassEntityPersister(
final PersistentClass persistentClass,
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext,
final EntityMetamodelFactory entityMetamodelFactory) throws HibernateException {
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext, entityMetamodelFactory );
final Dialect dialect = creationContext.getDialect();
final SqmFunctionRegistry functionRegistry = creationContext.getFunctionRegistry();

View File

@ -114,8 +114,20 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext) throws HibernateException {
this( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext, new EntityMetamodelFactory() );
}
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
/*
* Used by Hibernate Reactive
*/
public SingleTableEntityPersister(
final PersistentClass persistentClass,
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext,
final EntityMetamodelFactory entityMetamodelFactory) throws HibernateException {
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext, entityMetamodelFactory );
final Dialect dialect = creationContext.getDialect();
final SqmFunctionRegistry functionRegistry = creationContext.getFunctionRegistry();

View File

@ -95,7 +95,19 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext) throws HibernateException {
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
this( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext, new EntityMetamodelFactory() );
}
/*
* Used by Hibernate Reactive
*/
public UnionSubclassEntityPersister(
final PersistentClass persistentClass,
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext,
final EntityMetamodelFactory entityMetamodelFactory) throws HibernateException {
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext, entityMetamodelFactory );
validateGenerator();

View File

@ -13,6 +13,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
@ -149,6 +150,18 @@ public class EntityMetamodel implements Serializable {
PersistentClass persistentClass,
EntityPersister persister,
RuntimeModelCreationContext creationContext) {
this( persistentClass, persister, creationContext,
rootName -> buildIdGenerator( rootName, persistentClass, creationContext ) );
}
/*
* Used by Hibernate Reactive to adapt the id generators
*/
public EntityMetamodel(
PersistentClass persistentClass,
EntityPersister persister,
RuntimeModelCreationContext creationContext,
Function<String, Generator> generatorSupplier) {
this.sessionFactory = creationContext.getSessionFactory();
// Improves performance of EntityKey#equals by avoiding content check in String#equals
@ -160,7 +173,7 @@ public class EntityMetamodel implements Serializable {
subclassId = persistentClass.getSubclassId();
final Generator idgenerator = buildIdGenerator( persistentClass, creationContext );
final Generator idgenerator = generatorSupplier.apply( rootName );
identifierAttribute = PropertyFactory.buildIdentifierAttribute( persistentClass, idgenerator );
versioned = persistentClass.isVersioned();
@ -483,7 +496,7 @@ public class EntityMetamodel implements Serializable {
return writePropertyValue;
}
private Generator buildIdGenerator(PersistentClass persistentClass, RuntimeModelCreationContext creationContext) {
private static Generator buildIdGenerator(String rootName, PersistentClass persistentClass, RuntimeModelCreationContext creationContext) {
final Generator existing = creationContext.getGenerators().get( rootName );
if ( existing != null ) {
return existing;