allow @Formulas to refer to columns of @SecondaryTables
(this is something that was previously only possible using hbm.xml) also attempt a partial fixup of the initialization process where SessionFactoryImpl constructor leaked out an uninitialized reference to itself (it still leaks, but not as badly)
This commit is contained in:
parent
1eba25a466
commit
7aa92a7c05
|
@ -13,6 +13,7 @@ import jakarta.persistence.PersistenceException;
|
|||
|
||||
import jakarta.persistence.SecondaryTable;
|
||||
import org.hibernate.annotations.Check;
|
||||
import org.hibernate.annotations.Formula;
|
||||
import org.hibernate.annotations.NaturalId;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
|
@ -53,6 +54,11 @@ public class CheckTest extends BaseEntityManagerFunctionalTestCase {
|
|||
|
||||
entityManager.persist(book);
|
||||
});
|
||||
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
Book book = entityManager.find(Book.class, 0L);
|
||||
assertEquals( 1, book.edition );
|
||||
assertEquals( 2, book.nextEdition );
|
||||
});
|
||||
try {
|
||||
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
//tag::schema-generation-database-checks-persist-example[]
|
||||
|
@ -142,6 +148,9 @@ public class CheckTest extends BaseEntityManagerFunctionalTestCase {
|
|||
@Column(table = "BookEdition")
|
||||
private int edition = 1;
|
||||
|
||||
@Formula("edition + 1")
|
||||
private int nextEdition = 2;
|
||||
|
||||
@Column(table = "BookEdition")
|
||||
private LocalDate editionDate;
|
||||
|
||||
|
|
|
@ -17,13 +17,6 @@ import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
|||
*/
|
||||
@Deprecated(since = "6.0")
|
||||
public interface Metamodel extends JpaMetamodel {
|
||||
/**
|
||||
* Access to the SessionFactory that this Metamodel instance is bound to.
|
||||
*
|
||||
* @return The SessionFactory
|
||||
*/
|
||||
SessionFactory getSessionFactory();
|
||||
|
||||
/**
|
||||
* Given the name of an entity class, determine all the class and interface names by which it can be
|
||||
* referenced in an HQL query.
|
||||
|
|
|
@ -18,8 +18,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
*
|
||||
* @author Matthew Inger
|
||||
*
|
||||
* @deprecated Prefer the standard JPA {@link jakarta.persistence.OrderColumn} annotation and the Hibernate specific
|
||||
* {@link ListIndexBase} (for replacing {@link #base()}).
|
||||
* @deprecated Prefer the standard JPA {@link jakarta.persistence.OrderColumn} annotation,
|
||||
* using {@link ListIndexBase} instead of {@link #base()}.
|
||||
*/
|
||||
@Target({METHOD, FIELD})
|
||||
@Retention(RUNTIME)
|
||||
|
|
|
@ -13,8 +13,8 @@ import static java.lang.annotation.ElementType.TYPE;
|
|||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* A grouping of Hibernate-specific {@link NamedNativeQuery} definitions. Effectively extends the named native
|
||||
* query definitions made available through {@link jakarta.persistence.NamedNativeQueries}.
|
||||
* A grouping of {@link NamedNativeQuery} definitions. Extends the named native query
|
||||
* definitions made available through {@link jakarta.persistence.NamedNativeQueries}.
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
|
|
|
@ -13,8 +13,8 @@ import static java.lang.annotation.ElementType.TYPE;
|
|||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* A grouping of Hibernate-specific {@link NamedQuery} definitions. Effectively extends the named query
|
||||
* definitions made available through {@link jakarta.persistence.NamedQueries}.
|
||||
* A grouping of {@link NamedQuery} definitions. Extends the named query definitions
|
||||
* made available through {@link jakarta.persistence.NamedQueries}.
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
* @author Carlos Gonzalez-Cadenas
|
||||
|
|
|
@ -368,7 +368,7 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
|||
);
|
||||
}
|
||||
if ( inheritanceState.isEmbeddableSuperclass() ) {
|
||||
join.addMappedsuperclassProperty( property );
|
||||
join.addMappedSuperclassProperty( property );
|
||||
addPropertyToMappedSuperclass( property, declaringClass );
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.hibernate.context.internal.ManagedSessionContext;
|
|||
import org.hibernate.context.internal.ThreadLocalSessionContext;
|
||||
import org.hibernate.context.spi.CurrentSessionContext;
|
||||
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
|
@ -83,8 +84,10 @@ import org.hibernate.metadata.CollectionMetadata;
|
|||
import org.hibernate.metamodel.internal.RuntimeMetamodelsImpl;
|
||||
import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
|
||||
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.metamodel.spi.MetamodelImplementor;
|
||||
import org.hibernate.metamodel.spi.RuntimeMetamodelsImplementor;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Loadable;
|
||||
import org.hibernate.persister.entity.SessionFactoryBasedWrapperOptions;
|
||||
|
@ -100,6 +103,7 @@ import org.hibernate.query.spi.QueryEngine;
|
|||
import org.hibernate.query.spi.QueryImplementor;
|
||||
import org.hibernate.query.sql.spi.NativeQueryImplementor;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
|
||||
import org.hibernate.relational.SchemaManager;
|
||||
import org.hibernate.relational.internal.SchemaManagerImpl;
|
||||
|
@ -251,9 +255,79 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
|
||||
queryEngine = QueryEngine.from( this, bootMetamodel );
|
||||
|
||||
bootstrapContext.getTypeConfiguration().scope( this );
|
||||
|
||||
final RuntimeMetamodelsImpl runtimeMetamodelsImpl = new RuntimeMetamodelsImpl();
|
||||
runtimeMetamodels = runtimeMetamodelsImpl;
|
||||
runtimeMetamodelsImpl.finishInitialization( bootMetamodel, bootstrapContext, this );
|
||||
new RuntimeModelCreationContext() {
|
||||
final MappingMetamodelImpl mappingMetamodelImpl =
|
||||
new MappingMetamodelImpl( typeConfiguration, serviceRegistry, options.getJpaCompliance() );
|
||||
{
|
||||
// need to set this before calling finishInitialization()
|
||||
runtimeMetamodelsImpl.setMappingMetamodel( mappingMetamodelImpl );
|
||||
// because this calls back to the RuntimeMetamodelsImplementor
|
||||
mappingMetamodelImpl.finishInitialization( this );
|
||||
// need to set this after calling finishInitialization()
|
||||
runtimeMetamodelsImpl.setJpaMetamodel( mappingMetamodelImpl.getJpaMetamodel() );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public BootstrapContext getBootstrapContext() {
|
||||
return bootstrapContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
// this is bad, we're not yet fully-initialized
|
||||
return SessionFactoryImpl.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataImplementor getBootModel() {
|
||||
return bootMetamodel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingMetamodelImplementor getDomainModel() {
|
||||
return mappingMetamodelImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CacheImplementor getCache() {
|
||||
return cacheAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialect getDialect() {
|
||||
return jdbcServices.getDialect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmFunctionRegistry getFunctionRegistry() {
|
||||
return queryEngine.getSqmFunctionRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConfiguration getTypeConfiguration() {
|
||||
return typeConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryOptions getSessionFactoryOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcServices getJdbcServices() {
|
||||
return jdbcServices;
|
||||
}
|
||||
};
|
||||
|
||||
queryEngine.prepare( this, bootMetamodel, bootstrapContext );
|
||||
if ( options.isNamedQueryStartupCheckingEnabled() ) {
|
||||
|
@ -328,7 +402,7 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
return generators;
|
||||
}
|
||||
|
||||
private SqlStringGenerationContext createSqlStringGenerationContext(
|
||||
private static SqlStringGenerationContext createSqlStringGenerationContext(
|
||||
MetadataImplementor bootMetamodel,
|
||||
SessionFactoryOptions options,
|
||||
JdbcServices jdbcServices) {
|
||||
|
|
|
@ -22,11 +22,10 @@ public final class LockModeConverter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert from the Hibernate specific LockMode to the JPA defined LockModeType.
|
||||
* Convert from the Hibernate-specific {@link LockMode} to the JPA defined {@link LockModeType}.
|
||||
*
|
||||
* @param lockMode The Hibernate LockMode.
|
||||
*
|
||||
* @return The JPA LockModeType
|
||||
* @param lockMode The Hibernate {@link LockMode}.
|
||||
* @return The JPA {@link LockModeType}
|
||||
*/
|
||||
public static LockModeType convertToLockModeType(LockMode lockMode) {
|
||||
if ( lockMode == LockMode.NONE ) {
|
||||
|
@ -54,11 +53,10 @@ public final class LockModeConverter {
|
|||
|
||||
|
||||
/**
|
||||
* Convert from JPA defined LockModeType to Hibernate specific LockMode.
|
||||
* Convert from JPA defined {@link LockModeType} to Hibernate-specific {@link LockMode}.
|
||||
*
|
||||
* @param lockMode The JPA LockModeType
|
||||
*
|
||||
* @return The Hibernate LockMode.
|
||||
* @param lockMode The JPA {@link LockModeType}
|
||||
* @return The Hibernate {@link LockMode}.
|
||||
*/
|
||||
public static LockMode convertToLockMode(LockModeType lockMode) {
|
||||
switch ( lockMode ) {
|
||||
|
|
|
@ -26,5 +26,7 @@ public interface AttributeContainer {
|
|||
/**
|
||||
* Add a property to this {@link PersistentClass} or {@link Join}.
|
||||
*/
|
||||
void addProperty(Property attribute);
|
||||
void addProperty(Property property);
|
||||
boolean contains(Property property);
|
||||
Table getTable();
|
||||
}
|
||||
|
|
|
@ -51,12 +51,17 @@ public class Join implements AttributeContainer, Serializable {
|
|||
public void addProperty(Property property) {
|
||||
properties.add( property );
|
||||
declaredProperties.add( property );
|
||||
property.setPersistentClass( getPersistentClass() );
|
||||
property.setPersistentClass( persistentClass );
|
||||
}
|
||||
|
||||
public void addMappedsuperclassProperty( Property property ) {
|
||||
@Override
|
||||
public boolean contains(Property property) {
|
||||
return properties.contains( property );
|
||||
}
|
||||
|
||||
public void addMappedSuperclassProperty(Property property ) {
|
||||
properties.add( property );
|
||||
property.setPersistentClass( getPersistentClass() );
|
||||
property.setPersistentClass( persistentClass );
|
||||
}
|
||||
|
||||
public List<Property> getDeclaredProperties() {
|
||||
|
|
|
@ -23,19 +23,19 @@ import org.hibernate.boot.model.CustomSql;
|
|||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.OptimisticLockStyle;
|
||||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.FilterConfiguration;
|
||||
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||
import org.hibernate.internal.util.collections.JoinedList;
|
||||
import org.hibernate.internal.util.collections.SingletonIterator;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.jpa.event.spi.CallbackDefinition;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.sql.Alias;
|
||||
import org.hibernate.sql.Template;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
|
@ -44,6 +44,7 @@ import static java.util.Collections.unmodifiableList;
|
|||
import static java.util.Comparator.comparing;
|
||||
import static org.hibernate.internal.util.StringHelper.qualify;
|
||||
import static org.hibernate.internal.util.StringHelper.root;
|
||||
import static org.hibernate.sql.Template.collectColumnNames;
|
||||
|
||||
/**
|
||||
* A mapping model object that represents an {@linkplain jakarta.persistence.Entity entity class}.
|
||||
|
@ -301,10 +302,15 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addProperty(Property p) {
|
||||
properties.add( p );
|
||||
declaredProperties.add( p );
|
||||
p.setPersistentClass( this );
|
||||
public void addProperty(Property property) {
|
||||
properties.add( property );
|
||||
declaredProperties.add( property );
|
||||
property.setPersistentClass( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Property property) {
|
||||
return properties.contains( property );
|
||||
}
|
||||
|
||||
public abstract Table getTable();
|
||||
|
@ -1224,36 +1230,55 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
|||
|
||||
// End of @MappedSuperclass support
|
||||
|
||||
public void prepareForMappingModel() {
|
||||
public void prepareForMappingModel(RuntimeModelCreationContext context) {
|
||||
final Dialect dialect = context.getDialect();
|
||||
final TypeConfiguration typeConfiguration = context.getTypeConfiguration();
|
||||
final SqmFunctionRegistry functionRegistry = context.getFunctionRegistry();
|
||||
|
||||
// assign check constraints to the right table
|
||||
for ( CheckConstraint checkConstraint : checkConstraints ) {
|
||||
container( collectColumnNames( checkConstraint.getConstraint(), dialect, typeConfiguration, functionRegistry ) )
|
||||
.getTable().addCheck( checkConstraint );
|
||||
}
|
||||
|
||||
// now, move @Formulas to the correct AttributeContainers
|
||||
//TODO: skip this step for hbm.xml
|
||||
for ( Property property : new ArrayList<>( properties ) ) {
|
||||
for ( Selectable selectable : property.getSelectables() ) {
|
||||
if ( selectable.isFormula() && properties.contains( property ) ) {
|
||||
final Formula formula = (Formula) selectable;
|
||||
final AttributeContainer container =
|
||||
container( collectColumnNames( formula.getTemplate( dialect, typeConfiguration, functionRegistry ) ) );
|
||||
if ( !container.contains( property ) ) {
|
||||
properties.remove( property );
|
||||
container.addProperty( property );
|
||||
break; //TODO: embeddables
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
properties.sort( comparing( Property::getName ) );
|
||||
}
|
||||
|
||||
public void mappingModelReady(MappingMetamodel mappingMetamodel) {
|
||||
for ( CheckConstraint checkConstraint : checkConstraints ) {
|
||||
final TypeConfiguration typeConfiguration = mappingMetamodel.getTypeConfiguration();
|
||||
final SessionFactoryImplementor sessionFactory = typeConfiguration.getSessionFactory();
|
||||
final List<String> constrainedColumnNames =
|
||||
Template.collectColumnNames( checkConstraint.getConstraint(), typeConfiguration, sessionFactory );
|
||||
final Table primary = getTable();
|
||||
long matches = matchesInTable( constrainedColumnNames, primary );
|
||||
if ( matches == constrainedColumnNames.size() ) {
|
||||
// perfect, all columns matched in the primary table
|
||||
primary.addCheck( checkConstraint );
|
||||
}
|
||||
else {
|
||||
// go searching for a secondary table which better matches
|
||||
Table table = primary;
|
||||
long max = matches;
|
||||
for ( Join join : getJoins() ) {
|
||||
final Table secondary = join.getTable();
|
||||
long secondaryMatches = matchesInTable( constrainedColumnNames, secondary );
|
||||
if ( secondaryMatches > max ) {
|
||||
table = secondary;
|
||||
max = secondaryMatches;
|
||||
}
|
||||
private AttributeContainer container(List<String> constrainedColumnNames) {
|
||||
long matches = matchesInTable( constrainedColumnNames, getTable() );
|
||||
if ( matches == constrainedColumnNames.size() ) {
|
||||
// perfect, all columns matched in the primary table
|
||||
return this;
|
||||
}
|
||||
else {
|
||||
// go searching for a secondary table which better matches
|
||||
AttributeContainer result = this;
|
||||
long max = matches;
|
||||
for ( Join join : getJoins() ) {
|
||||
long secondaryMatches = matchesInTable( constrainedColumnNames, join.getTable() );
|
||||
if ( secondaryMatches > max ) {
|
||||
result = join;
|
||||
max = secondaryMatches;
|
||||
}
|
||||
table.addCheck( checkConstraint );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,15 +108,15 @@ public class Subclass extends PersistentClass {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addProperty(Property p) {
|
||||
super.addProperty(p);
|
||||
getSuperclass().addSubclassProperty(p);
|
||||
public void addProperty(Property property) {
|
||||
super.addProperty( property );
|
||||
getSuperclass().addSubclassProperty( property );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMappedSuperclassProperty(Property p) {
|
||||
super.addMappedSuperclassProperty( p );
|
||||
getSuperclass().addSubclassProperty(p);
|
||||
public void addMappedSuperclassProperty(Property property) {
|
||||
super.addMappedSuperclassProperty( property );
|
||||
getSuperclass().addSubclassProperty( property );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
package org.hibernate.metamodel;
|
||||
|
||||
/**
|
||||
* At the end of the day, any "value mapping" (id, version, attribute, collection element, etc) can be one
|
||||
* of a few classifications. This defines an enumeration of those classifications
|
||||
* At the end of the day, any "value mapping" (id, version, attribute, collection element, etc.)
|
||||
* can be one of a few classifications. This defines an enumeration of those classifications.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -18,9 +18,10 @@ public enum ValueClassification {
|
|||
*/
|
||||
BASIC,
|
||||
/**
|
||||
* ANY is a Hibernate specific concept. It is essentially a "reverse discrimination". Here, the association itself
|
||||
* defines a discriminator to the associated entity - sort of the reverse of discriminator-inheritance. Here the
|
||||
* various associated types can be unrelated in terms of mapped inheritance.
|
||||
* ANY is a Hibernate-specific concept. It is essentially a "reverse discrimination".
|
||||
* Here, the association itself defines a discriminator to the associated entity,
|
||||
* sort of the reverse of discriminator-inheritance. Here the various associated types
|
||||
* can be unrelated in terms of mapped inheritance.
|
||||
*/
|
||||
ANY,
|
||||
/**
|
||||
|
|
|
@ -6,12 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.internal;
|
||||
|
||||
import org.hibernate.boot.spi.BootstrapContext;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.internal.SessionFactoryImpl;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
|
||||
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.metamodel.spi.RuntimeMetamodelsImplementor;
|
||||
|
@ -46,22 +42,11 @@ public class RuntimeMetamodelsImpl implements RuntimeMetamodelsImplementor {
|
|||
return mappingMetamodel.getEmbeddableValuedModelPart( role );
|
||||
}
|
||||
|
||||
/**
|
||||
* Chicken-and-egg because things try to use the SessionFactory (specifically the MappingMetamodel)
|
||||
* before it is ready. So we do this fugly code...
|
||||
*/
|
||||
public void finishInitialization(
|
||||
MetadataImplementor bootMetamodel,
|
||||
BootstrapContext bootstrapContext,
|
||||
SessionFactoryImpl sessionFactory) {
|
||||
final MappingMetamodelImpl mappingMetamodel = bootstrapContext.getTypeConfiguration().scope( sessionFactory );
|
||||
public void setMappingMetamodel(MappingMetamodelImplementor mappingMetamodel) {
|
||||
this.mappingMetamodel = mappingMetamodel;
|
||||
mappingMetamodel.finishInitialization(
|
||||
bootMetamodel,
|
||||
bootstrapContext,
|
||||
sessionFactory
|
||||
);
|
||||
}
|
||||
|
||||
this.jpaMetamodel = mappingMetamodel.getJpaMetamodel();
|
||||
public void setJpaMetamodel(JpaMetamodelImplementor jpaMetamodel) {
|
||||
this.jpaMetamodel = jpaMetamodel;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,18 +32,15 @@ public class MappingModelCreationProcess {
|
|||
*/
|
||||
public static void process(
|
||||
Map<String,EntityPersister> entityPersisterMap,
|
||||
SqmFunctionRegistry functionRegistry,
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
final MappingModelCreationProcess process = new MappingModelCreationProcess(
|
||||
entityPersisterMap,
|
||||
functionRegistry,
|
||||
creationContext
|
||||
);
|
||||
process.execute();
|
||||
}
|
||||
|
||||
private final Map<String,EntityPersister> entityPersisterMap;
|
||||
private final SqmFunctionRegistry functionRegistry;
|
||||
|
||||
private final RuntimeModelCreationContext creationContext;
|
||||
|
||||
|
@ -53,10 +50,8 @@ public class MappingModelCreationProcess {
|
|||
|
||||
private MappingModelCreationProcess(
|
||||
Map<String, EntityPersister> entityPersisterMap,
|
||||
SqmFunctionRegistry functionRegistry,
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
this.entityPersisterMap = entityPersisterMap;
|
||||
this.functionRegistry = functionRegistry;
|
||||
this.creationContext = creationContext;
|
||||
}
|
||||
|
||||
|
@ -69,7 +64,7 @@ public class MappingModelCreationProcess {
|
|||
}
|
||||
|
||||
public SqmFunctionRegistry getSqmFunctionRegistry() {
|
||||
return functionRegistry;
|
||||
return creationContext.getFunctionRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,13 +25,11 @@ import org.hibernate.MappingException;
|
|||
import org.hibernate.UnknownEntityTypeException;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||
import org.hibernate.boot.spi.BootstrapContext;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.cache.spi.CacheImplementor;
|
||||
import org.hibernate.cache.spi.access.CollectionDataAccess;
|
||||
import org.hibernate.cache.spi.access.EntityDataAccess;
|
||||
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.graph.RootGraph;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.internal.EntityManagerMessageLogger;
|
||||
|
@ -43,8 +41,6 @@ import org.hibernate.mapping.Component;
|
|||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting;
|
||||
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||
|
@ -68,6 +64,7 @@ import org.hibernate.query.BindableType;
|
|||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
@ -104,8 +101,6 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
|
|||
|
||||
private static final String[] EMPTY_IMPLEMENTORS = ArrayHelper.EMPTY_STRING_ARRAY;
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// JpaMetamodel
|
||||
|
||||
|
@ -160,79 +155,50 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
|
|||
// private final Map<Class<?>, EmbeddableDomainType<?>> jpaEmbeddableTypeMap = new ConcurrentHashMap<>();
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
private final ServiceRegistry serviceRegistry;
|
||||
private final TypeConfiguration typeConfiguration;
|
||||
|
||||
private final Map<String, String[]> implementorsCache = new ConcurrentHashMap<>();
|
||||
private final Map<TupleType<?>, MappingModelExpressible<?>> tupleTypeCache = new ConcurrentHashMap<>();
|
||||
|
||||
public MappingMetamodelImpl(SessionFactoryImplementor sessionFactory, TypeConfiguration typeConfiguration) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
public MappingMetamodelImpl(
|
||||
TypeConfiguration typeConfiguration,
|
||||
ServiceRegistry serviceRegistry,
|
||||
JpaCompliance jpaCompliance) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
this.typeConfiguration = typeConfiguration;
|
||||
this.jpaMetamodel = new JpaMetamodelImpl( typeConfiguration, sessionFactory.getSessionFactoryOptions().getJpaCompliance() );
|
||||
this.jpaMetamodel = new JpaMetamodelImpl( typeConfiguration, jpaCompliance );
|
||||
}
|
||||
|
||||
public JpaMetamodelImplementor getJpaMetamodel() {
|
||||
return jpaMetamodel;
|
||||
}
|
||||
|
||||
public void finishInitialization(
|
||||
MetadataImplementor bootModel,
|
||||
BootstrapContext bootstrapContext,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
final RuntimeModelCreationContext runtimeModelCreationContext = new RuntimeModelCreationContext() {
|
||||
@Override
|
||||
public BootstrapContext getBootstrapContext() {
|
||||
return bootstrapContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataImplementor getBootModel() {
|
||||
return bootModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingMetamodel getDomainModel() {
|
||||
return MappingMetamodelImpl.this;
|
||||
}
|
||||
};
|
||||
|
||||
final PersisterFactory persisterFactory = sessionFactory.getServiceRegistry().getService( PersisterFactory.class );
|
||||
|
||||
final JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting = determineJpaStaticMetaModelPopulationSetting( sessionFactory.getProperties() );
|
||||
final JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting = determineJpaMetaModelPopulationSetting( sessionFactory.getProperties() );
|
||||
|
||||
public void finishInitialization(RuntimeModelCreationContext context) {
|
||||
final MetadataImplementor bootModel = context.getBootModel();
|
||||
bootModel.visitRegisteredComponents( Component::prepareForMappingModel );
|
||||
bootModel.getMappedSuperclassMappingsCopy().forEach( MappedSuperclass::prepareForMappingModel );
|
||||
bootModel.getEntityBindings().forEach( PersistentClass::prepareForMappingModel );
|
||||
bootModel.getEntityBindings().forEach( persistentClass -> persistentClass.prepareForMappingModel( context ) );
|
||||
|
||||
final PersisterFactory persisterFactory = serviceRegistry.getService( PersisterFactory.class );
|
||||
final CacheImplementor cache = context.getCache();
|
||||
processBootEntities(
|
||||
bootModel.getEntityBindings(),
|
||||
sessionFactory.getCache(),
|
||||
cache,
|
||||
persisterFactory,
|
||||
runtimeModelCreationContext
|
||||
context
|
||||
);
|
||||
|
||||
processBootCollections(
|
||||
bootModel.getCollectionBindings(),
|
||||
sessionFactory.getCache(),
|
||||
cache,
|
||||
persisterFactory,
|
||||
runtimeModelCreationContext
|
||||
context
|
||||
);
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// after *all* persisters and named queries are registered
|
||||
|
||||
MappingModelCreationProcess.process(
|
||||
entityPersisterMap,
|
||||
sessionFactory.getQueryEngine().getSqmFunctionRegistry(),
|
||||
runtimeModelCreationContext
|
||||
);
|
||||
MappingModelCreationProcess.process( entityPersisterMap, context );
|
||||
|
||||
for ( EntityPersister persister : entityPersisterMap.values() ) {
|
||||
persister.postInstantiate();
|
||||
|
@ -243,18 +209,16 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
|
|||
|
||||
registerEmbeddableMappingType( bootModel );
|
||||
|
||||
( (JpaMetamodelImpl) this.jpaMetamodel ).processJpa(
|
||||
final Map<String, Object> settings = context.getSettings();
|
||||
( (JpaMetamodelImpl) jpaMetamodel ).processJpa(
|
||||
bootModel,
|
||||
this,
|
||||
entityProxyInterfaceMap,
|
||||
jpaStaticMetaModelPopulationSetting,
|
||||
jpaMetaModelPopulationSetting,
|
||||
determineJpaStaticMetaModelPopulationSetting( settings ),
|
||||
determineJpaMetaModelPopulationSetting( settings ),
|
||||
bootModel.getNamedEntityGraphs().values(),
|
||||
runtimeModelCreationContext
|
||||
context
|
||||
);
|
||||
|
||||
bootModel.getEntityBindings().forEach( persistentClass -> persistentClass.mappingModelReady( this ) );
|
||||
|
||||
}
|
||||
|
||||
private void registerEmbeddableMappingType(MetadataImplementor bootModel) {
|
||||
|
@ -452,11 +416,6 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
|
|||
return entityPersisterMap.containsKey( entityJavaType.getName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister getEntityDescriptor(Class<?> entityJavaType) {
|
||||
EntityPersister entityPersister = entityPersisterMap.get( entityJavaType.getName() );
|
||||
|
@ -566,9 +525,7 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
|
|||
}
|
||||
|
||||
try {
|
||||
final Class<?> clazz = getSessionFactory().getServiceRegistry()
|
||||
.getService( ClassLoaderService.class )
|
||||
.classForName( className );
|
||||
final Class<?> clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( className );
|
||||
implementors = doGetImplementors( clazz );
|
||||
if ( implementors.length > 0 ) {
|
||||
implementorsCache.putIfAbsent( className, implementors );
|
||||
|
|
|
@ -29,10 +29,6 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
*/
|
||||
@Deprecated(since = "6.0")
|
||||
public interface MetamodelImplementor extends MappingMetamodel, Metamodel {
|
||||
|
||||
@Override
|
||||
SessionFactoryImplementor getSessionFactory();
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link MappingMetamodelImplementor#getEntityNameResolvers} instead
|
||||
*/
|
||||
|
|
|
@ -8,13 +8,18 @@ package org.hibernate.metamodel.spi;
|
|||
|
||||
import org.hibernate.boot.spi.BootstrapContext;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.cache.spi.CacheImplementor;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -25,16 +30,12 @@ public interface RuntimeModelCreationContext extends PersisterCreationContext {
|
|||
|
||||
MetadataImplementor getBootModel();
|
||||
|
||||
MappingMetamodel getDomainModel();
|
||||
MappingMetamodelImplementor getDomainModel();
|
||||
|
||||
default TypeConfiguration getTypeConfiguration() {
|
||||
return getBootstrapContext().getTypeConfiguration();
|
||||
}
|
||||
|
||||
default ManagedBeanRegistry getManagedBeanRegistry() {
|
||||
return getSessionFactory().getServiceRegistry().getService( ManagedBeanRegistry.class );
|
||||
}
|
||||
|
||||
default JavaTypeRegistry getJavaTypeRegistry() {
|
||||
return getTypeConfiguration().getJavaTypeRegistry();
|
||||
}
|
||||
|
@ -43,4 +44,16 @@ public interface RuntimeModelCreationContext extends PersisterCreationContext {
|
|||
default MetadataImplementor getMetadata() {
|
||||
return getBootModel();
|
||||
}
|
||||
|
||||
SqmFunctionRegistry getFunctionRegistry();
|
||||
|
||||
Map<String, Object> getSettings();
|
||||
|
||||
Dialect getDialect();
|
||||
|
||||
CacheImplementor getCache();
|
||||
|
||||
SessionFactoryOptions getSessionFactoryOptions();
|
||||
|
||||
JdbcServices getJdbcServices();
|
||||
}
|
||||
|
|
|
@ -487,12 +487,14 @@ public abstract class AbstractEntityPersister
|
|||
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
|
||||
final RuntimeModelCreationContext creationContext) throws HibernateException {
|
||||
|
||||
//set it here, but don't call it, since it's still uninitialized!
|
||||
factory = creationContext.getSessionFactory();
|
||||
|
||||
sqlAliasStem = SqlAliasStemHelper.INSTANCE.generateStemFromEntityName( persistentClass.getEntityName() );
|
||||
|
||||
navigableRole = new NavigableRole( persistentClass.getEntityName() );
|
||||
|
||||
final SessionFactoryOptions sessionFactoryOptions = creationContext.getSessionFactory().getSessionFactoryOptions();
|
||||
final SessionFactoryOptions sessionFactoryOptions = creationContext.getSessionFactoryOptions();
|
||||
|
||||
if ( sessionFactoryOptions.isSecondLevelCacheEnabled() ) {
|
||||
this.cacheAccessStrategy = cacheAccessStrategy;
|
||||
|
@ -1069,8 +1071,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
private boolean isCacheComplianceEnabled(RuntimeModelCreationContext creationContext) {
|
||||
return creationContext.getSessionFactory()
|
||||
.getSessionFactoryOptions()
|
||||
return creationContext.getSessionFactoryOptions()
|
||||
.getJpaCompliance()
|
||||
.isJpaCacheComplianceEnabled();
|
||||
}
|
||||
|
@ -4752,8 +4753,7 @@ public abstract class AbstractEntityPersister
|
|||
else {
|
||||
sqmMultiTableMutationStrategy.prepare(
|
||||
creationProcess,
|
||||
creationContext.getSessionFactory().getJdbcServices()
|
||||
.getBootstrapJdbcConnectionAccess()
|
||||
creationContext.getJdbcServices().getBootstrapJdbcConnectionAccess()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -4784,8 +4784,7 @@ public abstract class AbstractEntityPersister
|
|||
else {
|
||||
sqmMultiTableInsertStrategy.prepare(
|
||||
creationProcess,
|
||||
creationContext.getSessionFactory().getJdbcServices()
|
||||
.getBootstrapJdbcConnectionAccess()
|
||||
creationContext.getJdbcServices().getBootstrapJdbcConnectionAccess()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import org.hibernate.boot.spi.BootstrapContext;
|
|||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
|
@ -34,10 +33,6 @@ public interface PersisterCreationContext {
|
|||
|
||||
MetadataImplementor getMetadata();
|
||||
|
||||
default ManagedBeanRegistry getManagedBeanRegistry() {
|
||||
return getSessionFactory().getServiceRegistry().getService( ManagedBeanRegistry.class );
|
||||
}
|
||||
|
||||
default JavaTypeRegistry getJavaTypeRegistry() {
|
||||
return getTypeConfiguration().getJavaTypeRegistry();
|
||||
}
|
||||
|
|
|
@ -362,15 +362,14 @@ public final class Template {
|
|||
}
|
||||
|
||||
public static List<String> collectColumnNames(
|
||||
String checkConstraint,
|
||||
String sql,
|
||||
Dialect dialect,
|
||||
TypeConfiguration typeConfiguration,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
final String template = renderWhereStringTemplate(
|
||||
checkConstraint,
|
||||
sessionFactory.getJdbcServices().getDialect(),
|
||||
typeConfiguration,
|
||||
sessionFactory.getQueryEngine().getSqmFunctionRegistry()
|
||||
);
|
||||
SqmFunctionRegistry functionRegistry) {
|
||||
return collectColumnNames( renderWhereStringTemplate( sql, dialect, typeConfiguration, functionRegistry ) );
|
||||
}
|
||||
|
||||
public static List<String> collectColumnNames(String template) {
|
||||
final List<String> names = new ArrayList<>();
|
||||
int begin = 0;
|
||||
int match;
|
||||
|
|
|
@ -49,7 +49,6 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
|
|||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||
import org.hibernate.metamodel.model.domain.internal.ArrayTupleType;
|
||||
import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
|
||||
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
||||
import org.hibernate.query.sqm.IntervalType;
|
||||
import org.hibernate.query.internal.QueryHelper;
|
||||
|
@ -156,25 +155,39 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
|||
// Scoping
|
||||
|
||||
/**
|
||||
* Obtain the MetadataBuildingContext currently scoping the
|
||||
* TypeConfiguration.
|
||||
* Obtain the {@link MetadataBuildingContext} currently scoping this
|
||||
* {@code TypeConfiguration}.
|
||||
*
|
||||
* @apiNote This will throw an exception if the SessionFactory is not yet
|
||||
* bound here. See {@link Scope} for more details regarding the stages
|
||||
* a TypeConfiguration goes through
|
||||
*
|
||||
* @return The MetadataBuildingContext
|
||||
* @return The {@link MetadataBuildingContext}
|
||||
*/
|
||||
public MetadataBuildingContext getMetadataBuildingContext() {
|
||||
return scope.getMetadataBuildingContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope this {@code TypeConfiguration} to the given {@link MetadataBuildingContext}.
|
||||
*
|
||||
* @implNote The given factory is not yet fully-initialized!
|
||||
*
|
||||
* @param metadataBuildingContext a {@link MetadataBuildingContext}
|
||||
*/
|
||||
public void scope(MetadataBuildingContext metadataBuildingContext) {
|
||||
log.debugf( "Scoping TypeConfiguration [%s] to MetadataBuildingContext [%s]", this, metadataBuildingContext );
|
||||
scope.setMetadataBuildingContext( metadataBuildingContext );
|
||||
}
|
||||
|
||||
public MappingMetamodelImpl scope(SessionFactoryImplementor sessionFactory) {
|
||||
/**
|
||||
* Scope this {@code TypeConfiguration} to the given {@link SessionFactory}.
|
||||
*
|
||||
* @implNote The given factory is not yet fully-initialized!
|
||||
*
|
||||
* @param sessionFactory a {@link SessionFactory} that is in a very fragile state
|
||||
*/
|
||||
public void scope(SessionFactoryImplementor sessionFactory) {
|
||||
log.debugf( "Scoping TypeConfiguration [%s] to SessionFactoryImplementor [%s]", this, sessionFactory );
|
||||
|
||||
if ( scope.getMetadataBuildingContext() == null ) {
|
||||
|
@ -183,33 +196,31 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
|||
|
||||
scope.setSessionFactory( sessionFactory );
|
||||
sessionFactory.addObserver( this );
|
||||
|
||||
return new MappingMetamodelImpl( sessionFactory, this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the SessionFactory currently scoping the TypeConfiguration.
|
||||
* Obtain the {@link SessionFactory} currently scoping the {@code TypeConfiguration}.
|
||||
*
|
||||
* @apiNote This will throw an exception if the SessionFactory is not yet
|
||||
* bound here. See {@link Scope} for more details regarding the stages
|
||||
* a TypeConfiguration goes through (this is "runtime stage")
|
||||
* @apiNote Throws an exception if the {@code TypeConfiguration} is not yet scoped to
|
||||
* a factory. See {@link Scope} for more details regarding the stages a
|
||||
* {@code TypeConfiguration} passes through (this is a "runtime stage").
|
||||
*
|
||||
* @return The SessionFactory
|
||||
* @return The {@link SessionFactory} to which this {@code TypeConfiguration} is scoped
|
||||
*
|
||||
* @throws IllegalStateException if the TypeConfiguration is currently not
|
||||
* associated with a SessionFactory (in "runtime stage").
|
||||
* @throws HibernateException if the {@code TypeConfiguration} is not currently scoped
|
||||
* to a {@link SessionFactory} (in a "runtime stage").
|
||||
*/
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return scope.getSessionFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the ServiceRegistry scoped to the TypeConfiguration.
|
||||
* Obtain the {@link ServiceRegistry} scoped to the {@code TypeConfiguration}.
|
||||
*
|
||||
* @apiNote Depending on what the {@link Scope} is currently scoped to will determine where the
|
||||
* {@link ServiceRegistry} is obtained from.
|
||||
* @apiNote The current {@link Scope} will determine from where the {@link ServiceRegistry}
|
||||
* is obtained.
|
||||
*
|
||||
* @return The ServiceRegistry
|
||||
* @return The {@link ServiceRegistry} for the current scope
|
||||
*/
|
||||
public ServiceRegistry getServiceRegistry() {
|
||||
return scope.getServiceRegistry();
|
||||
|
@ -323,30 +334,32 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Encapsulation of lifecycle concerns for a TypeConfiguration:<ol>
|
||||
* Encapsulation of lifecycle concerns of a {@link TypeConfiguration}:
|
||||
* <ol>
|
||||
* <li>
|
||||
* "Boot" is where the {@link TypeConfiguration} is first
|
||||
* built as the boot-model ({@link org.hibernate.boot.model}) of
|
||||
* the user's domain model is converted into the runtime-model
|
||||
* ({@link org.hibernate.metamodel.model}). During this phase,
|
||||
* {@link #getMetadataBuildingContext()} will be accessible but
|
||||
* {@link #getSessionFactory} will throw an exception.
|
||||
* "Boot" is where the {@link TypeConfiguration} is first built as
|
||||
* {@linkplain org.hibernate.boot.model the boot model} of the domain
|
||||
* model is converted into {@linkplain org.hibernate.metamodel.model
|
||||
* the runtime model}. During this phase,
|
||||
* {@link #getMetadataBuildingContext()} is accessible but
|
||||
* {@link #getSessionFactory} throws an exception.
|
||||
* </li>
|
||||
* <li>
|
||||
* "Runtime" is where the runtime-model is accessible. During this
|
||||
* phase {@link #getSessionFactory()} is accessible while
|
||||
* {@link #getMetadataBuildingContext()} will now throw an exception
|
||||
* "Runtime" is where the runtime model is accessible. During this
|
||||
* phase, {@link #getSessionFactory()} is accessible but
|
||||
* {@link #getMetadataBuildingContext()} throws an exception.
|
||||
* </li>
|
||||
* <li>
|
||||
* "Sunset" is after the SessionFactory has been closed. At this point, both
|
||||
* {@link #getSessionFactory()} and {@link #getMetadataBuildingContext()}
|
||||
* will now throw an exception
|
||||
* "Sunset" happens after the {@link SessionFactory} has been closed.
|
||||
* Both {@link #getSessionFactory()} and {@link #getMetadataBuildingContext()}
|
||||
* throw exceptions.
|
||||
* </li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* {@link #getServiceRegistry()} is available for both "Boot" and "Runtime".
|
||||
*
|
||||
* Each stage or phase is consider a scope for the TypeConfiguration.
|
||||
* On the other hand, the {@linkplain #getServiceRegistry() service registry}
|
||||
* is available during both "Boot" and "Runtime" phases.
|
||||
* <p>
|
||||
* Each stage or phase is considered a scope for the {@link TypeConfiguration}.
|
||||
*/
|
||||
private static class Scope implements Serializable {
|
||||
private final TypeConfiguration typeConfiguration;
|
||||
|
@ -456,9 +469,9 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Used by TypeFactory scoping.
|
||||
* Used by {@link TypeConfiguration} scoping.
|
||||
*
|
||||
* @param factory The SessionFactory that the TypeFactory is being bound to
|
||||
* @param factory The {@link SessionFactory} to which the {@link TypeConfiguration} is being bound
|
||||
*/
|
||||
void setSessionFactory(SessionFactoryImplementor factory) {
|
||||
if ( this.sessionFactory != null ) {
|
||||
|
@ -466,15 +479,15 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
|||
}
|
||||
else {
|
||||
this.sessionFactoryUuid = factory.getUuid();
|
||||
String sfName = factory.getSessionFactoryOptions().getSessionFactoryName();
|
||||
if ( sfName == null ) {
|
||||
String factoryName = factory.getSessionFactoryOptions().getSessionFactoryName();
|
||||
if ( factoryName == null ) {
|
||||
final CfgXmlAccessService cfgXmlAccessService = factory.getServiceRegistry()
|
||||
.getService( CfgXmlAccessService.class );
|
||||
if ( cfgXmlAccessService.getAggregatedConfig() != null ) {
|
||||
sfName = cfgXmlAccessService.getAggregatedConfig().getSessionFactoryName();
|
||||
factoryName = cfgXmlAccessService.getAggregatedConfig().getSessionFactoryName();
|
||||
}
|
||||
}
|
||||
this.sessionFactoryName = sfName;
|
||||
this.sessionFactoryName = factoryName;
|
||||
}
|
||||
this.sessionFactory = factory;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ import org.junit.jupiter.api.Test;
|
|||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests Hibernate specific feature that {@link org.hibernate.annotations.SortNatural @SortNatural} will take effect implicitly
|
||||
* when no <i>sort</i> or <i>order</i> related annotations exist, including:
|
||||
* Tests Hibernate-specific feature that {@link org.hibernate.annotations.SortNatural @SortNatural}
|
||||
* will take effect implicitly when no <i>sort</i> or <i>order</i> related annotations exist, including:
|
||||
* <ul>
|
||||
* <li>{@link org.hibernate.annotations.SortNatural @SortNatural}</li>
|
||||
* <li>{@link org.hibernate.annotations.SortComparator @SortComparator}</li>
|
||||
|
|
|
@ -35,15 +35,13 @@ public class MetadataBuildingContextTestingImpl implements MetadataBuildingConte
|
|||
buildingOptions.setBootstrapContext( bootstrapContext = new BootstrapContextImpl( serviceRegistry, buildingOptions ) );
|
||||
mappingDefaults = new MetadataBuilderImpl.MappingDefaultsImpl( serviceRegistry );
|
||||
metadataCollector = new InFlightMetadataCollectorImpl( bootstrapContext, buildingOptions );
|
||||
|
||||
objectNameNormalizer = new ObjectNameNormalizer() {
|
||||
@Override
|
||||
protected MetadataBuildingContext getBuildingContext() {
|
||||
return MetadataBuildingContextTestingImpl.this;
|
||||
}
|
||||
};
|
||||
|
||||
this.typeDefinitionRegistry = new TypeDefinitionRegistryStandardImpl();
|
||||
typeDefinitionRegistry = new TypeDefinitionRegistryStandardImpl();
|
||||
bootstrapContext.getTypeConfiguration().scope( this );
|
||||
}
|
||||
|
||||
|
|
|
@ -34,14 +34,14 @@ import org.hibernate.jpamodelgen.util.TypeUtils;
|
|||
public class MetaAttributeGenerationVisitor extends SimpleTypeVisitor6<AnnotationMetaAttribute, Element> {
|
||||
|
||||
/**
|
||||
* FQCN of the Hibernate specific @Target annotation. We do not use the class directly to avoid depending on Hibernate
|
||||
* Core.
|
||||
* FQCN of the Hibernate-specific {@code @Target} annotation.
|
||||
* We do not use the class directly to avoid depending on Hibernate Core.
|
||||
*/
|
||||
private static final String ORG_HIBERNATE_ANNOTATIONS_TARGET = "org.hibernate.annotations.Target";
|
||||
|
||||
/**
|
||||
* FQCN of the Hibernate specific @Type annotation. We do not use the class directly to avoid depending on Hibernate
|
||||
* Core.
|
||||
* FQCN of the Hibernate-specific {@code @Type} annotation.
|
||||
* We do not use the class directly to avoid depending on Hibernate Core.
|
||||
*/
|
||||
private static final String ORG_HIBERNATE_ANNOTATIONS_TYPE = "org.hibernate.annotations.Type";
|
||||
|
||||
|
|
Loading…
Reference in New Issue