HHH-17504 - Ongoing JPA 32 work
HHH-17350 - Work on hibernate-models, XSD and JAXB HHH-16114 - Improve boot metamodel binding HHH-15996 - Develop an abstraction for Annotation in annotation processing HHH-16012 - Develop an abstraction for domain model Class refs HHH-15997 - Support for dynamic models in orm.xml HHH-15698 - Support for entity-name in mapping.xsd
This commit is contained in:
parent
3e20e0939f
commit
2eb3da331b
|
@ -10,6 +10,12 @@ import org.hibernate.Internal;
|
||||||
|
|
||||||
import org.jboss.logging.BasicLogger;
|
import org.jboss.logging.BasicLogger;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
import org.jboss.logging.annotations.LogMessage;
|
||||||
|
import org.jboss.logging.annotations.Message;
|
||||||
|
import org.jboss.logging.annotations.MessageLogger;
|
||||||
|
import org.jboss.logging.annotations.ValidIdRange;
|
||||||
|
|
||||||
|
import static org.jboss.logging.Logger.Level.INFO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* todo : find the proper min/max id range
|
* todo : find the proper min/max id range
|
||||||
|
@ -17,8 +23,19 @@ import org.jboss.logging.Logger;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
|
@MessageLogger( projectCode = "HHH" )
|
||||||
|
@ValidIdRange( min = 999980, max = 999999 )
|
||||||
public interface ModelBindingLogging extends BasicLogger {
|
public interface ModelBindingLogging extends BasicLogger {
|
||||||
String NAME = "org.hibernate.models.orm";
|
String NAME = "org.hibernate.models.orm";
|
||||||
|
|
||||||
Logger MODEL_BINDING_LOGGER = Logger.getLogger( NAME );
|
Logger MODEL_BINDING_LOGGER = Logger.getLogger( NAME );
|
||||||
|
ModelBindingLogging MODEL_BINDING_MSG_LOGGER = Logger.getMessageLogger( ModelBindingLogging.class, NAME );
|
||||||
|
|
||||||
|
@LogMessage(level = INFO)
|
||||||
|
@Message( id = 999980, value = "Entity `%s` used both @DynamicInsert and @SQLInsert" )
|
||||||
|
void dynamicAndCustomInsert(String entityName);
|
||||||
|
|
||||||
|
@LogMessage(level = INFO)
|
||||||
|
@Message( id = 999981, value = "Entity `%s` used both @DynamicUpdate and @SQLUpdate" )
|
||||||
|
void dynamicAndCustomUpdate(String entityName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Convert;
|
import jakarta.persistence.Convert;
|
||||||
|
|
||||||
import static org.hibernate.boot.models.categorize.spi.AttributeMetadata.AttributeNature.BASIC;
|
import static org.hibernate.boot.models.categorize.spi.AttributeMetadata.AttributeNature.BASIC;
|
||||||
|
import static org.hibernate.boot.models.categorize.spi.AttributeMetadata.AttributeNature.EMBEDDED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binding for an attribute
|
* Binding for an attribute
|
||||||
|
@ -61,16 +62,21 @@ public class AttributeBinding extends Binding {
|
||||||
this.property = new Property();
|
this.property = new Property();
|
||||||
this.property.setName( attributeMetadata.getName() );
|
this.property.setName( attributeMetadata.getName() );
|
||||||
|
|
||||||
|
final Value value;
|
||||||
if ( attributeMetadata.getNature() == BASIC ) {
|
if ( attributeMetadata.getNature() == BASIC ) {
|
||||||
final var basicValue = createBasicValue( primaryTable );
|
value = createBasicValue( primaryTable );
|
||||||
property.setValue( basicValue );
|
}
|
||||||
attributeTable = basicValue.getTable();
|
else if ( attributeMetadata.getNature() == EMBEDDED ) {
|
||||||
mappingValue = basicValue;
|
value = createComponentValue( primaryTable, owner );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException( "Not yet implemented" );
|
throw new UnsupportedOperationException( "Not yet implemented" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property.setValue( value );
|
||||||
|
attributeTable = value.getTable();
|
||||||
|
mappingValue = value;
|
||||||
|
|
||||||
applyNaturalId( attributeMetadata, property );
|
applyNaturalId( attributeMetadata, property );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +138,16 @@ public class AttributeBinding extends Binding {
|
||||||
return basicValue;
|
return basicValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Component createComponentValue(Table primaryTable, PersistentClass persistentClass) {
|
||||||
|
final Component component = new Component( bindingState.getMetadataBuildingContext(), persistentClass );
|
||||||
|
|
||||||
|
// 1. embeddable (attributes, etc)
|
||||||
|
// 2. overrides
|
||||||
|
final MemberDetails member = attributeMetadata.getMember();
|
||||||
|
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
public Property getProperty() {
|
public Property getProperty() {
|
||||||
return property;
|
return property;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.hibernate.boot.model.naming.Identifier;
|
import org.hibernate.boot.model.naming.Identifier;
|
||||||
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
|
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
|
||||||
import org.hibernate.boot.models.bind.spi.BindingContext;
|
|
||||||
import org.hibernate.boot.models.bind.spi.BindingOptions;
|
import org.hibernate.boot.models.bind.spi.BindingOptions;
|
||||||
import org.hibernate.boot.models.bind.spi.BindingState;
|
import org.hibernate.boot.models.bind.spi.BindingState;
|
||||||
import org.hibernate.boot.models.bind.spi.QuotedIdentifierTarget;
|
import org.hibernate.boot.models.bind.spi.QuotedIdentifierTarget;
|
||||||
|
@ -21,7 +20,6 @@ import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.models.ModelsException;
|
import org.hibernate.models.ModelsException;
|
||||||
import org.hibernate.models.spi.AnnotationDescriptor;
|
import org.hibernate.models.spi.AnnotationDescriptor;
|
||||||
import org.hibernate.models.spi.AnnotationUsage;
|
import org.hibernate.models.spi.AnnotationUsage;
|
||||||
import org.hibernate.models.spi.AttributeDescriptor;
|
|
||||||
|
|
||||||
import static org.hibernate.boot.models.bind.ModelBindingLogging.MODEL_BINDING_LOGGER;
|
import static org.hibernate.boot.models.bind.ModelBindingLogging.MODEL_BINDING_LOGGER;
|
||||||
|
|
||||||
|
@ -29,69 +27,6 @@ import static org.hibernate.boot.models.bind.ModelBindingLogging.MODEL_BINDING_L
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class BindingHelper {
|
public class BindingHelper {
|
||||||
public static <T, A extends Annotation> T getValue(
|
|
||||||
AnnotationUsage<A> annotationUsage,
|
|
||||||
String attributeName,
|
|
||||||
Class<A> annotationType,
|
|
||||||
BindingContext context) {
|
|
||||||
final T valueOrNull = getValueOrNull( annotationUsage, attributeName );
|
|
||||||
if ( valueOrNull != null ) {
|
|
||||||
return valueOrNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolve its default
|
|
||||||
return getDefaultValue( attributeName, annotationType, context );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, A extends Annotation> T getValueOrNull(
|
|
||||||
AnnotationUsage<A> annotationUsage,
|
|
||||||
String attributeName) {
|
|
||||||
if ( annotationUsage != null ) {
|
|
||||||
// allow to return null if missing
|
|
||||||
return annotationUsage.getAttributeValue( attributeName );
|
|
||||||
}
|
|
||||||
|
|
||||||
// there was no annotation...
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T,A extends Annotation> T getDefaultValue(
|
|
||||||
String attributeName,
|
|
||||||
Class<A> annotationType,
|
|
||||||
BindingContext context) {
|
|
||||||
final AnnotationDescriptor<A> annotationDescriptor = context.getAnnotationDescriptorRegistry().getDescriptor( annotationType );
|
|
||||||
final AttributeDescriptor<Object> attributeDescriptor = annotationDescriptor.getAttribute( attributeName );
|
|
||||||
//noinspection unchecked
|
|
||||||
return (T) attributeDescriptor.getAttributeMethod().getDefaultValue();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <A extends Annotation> String getString(
|
|
||||||
AnnotationUsage<A> annotationUsage,
|
|
||||||
String attributeName,
|
|
||||||
Class<A> annotationType,
|
|
||||||
BindingContext context) {
|
|
||||||
return getValue( annotationUsage, attributeName, annotationType, context );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <A extends Annotation> String getStringOrNull(
|
|
||||||
AnnotationUsage<A> annotationUsage,
|
|
||||||
String attributeName) {
|
|
||||||
return getValueOrNull( annotationUsage, attributeName );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <A extends Annotation> Identifier getIdentifier(
|
|
||||||
AnnotationUsage<A> annotationUsage,
|
|
||||||
String attributeName,
|
|
||||||
Class<A> annotationType,
|
|
||||||
QuotedIdentifierTarget target,
|
|
||||||
BindingOptions options,
|
|
||||||
JdbcEnvironment jdbcEnvironment,
|
|
||||||
BindingContext context) {
|
|
||||||
final String name = getString( annotationUsage, attributeName, annotationType, context );
|
|
||||||
final boolean globallyQuoted = options.getGloballyQuotedIdentifierTargets().contains( target );
|
|
||||||
return jdbcEnvironment.getIdentifierHelper().toIdentifier( name, globallyQuoted );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <A extends Annotation> Identifier toIdentifier(
|
public static <A extends Annotation> Identifier toIdentifier(
|
||||||
String name,
|
String name,
|
||||||
|
@ -116,17 +51,12 @@ public class BindingHelper {
|
||||||
return (T) descriptor.getAttribute( attributeName ).getAttributeMethod().getDefaultValue();
|
return (T) descriptor.getAttribute( attributeName ).getAttributeMethod().getDefaultValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
//noinspection unchecked
|
return ann.getAttributeValue( attributeName );
|
||||||
return getValue(
|
|
||||||
ann,
|
|
||||||
attributeName,
|
|
||||||
() -> (T) descriptor.getAttribute( attributeName ).getAttributeMethod().getDefaultValue()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T,A extends Annotation> T getValue(AnnotationUsage<A> ann, String attributeName, Supplier<T> defaultValueSupplier) {
|
public static <T,A extends Annotation> T getValue(AnnotationUsage<A> ann, String attributeName, Supplier<T> defaultValueSupplier) {
|
||||||
if ( ann == null ) {
|
if ( ann == null ) {
|
||||||
return (T) defaultValueSupplier.get();
|
return defaultValueSupplier.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ann.getAttributeValue( attributeName, defaultValueSupplier );
|
return ann.getAttributeValue( attributeName, defaultValueSupplier );
|
||||||
|
|
|
@ -6,14 +6,26 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.boot.models.bind.internal;
|
package org.hibernate.boot.models.bind.internal;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.BatchSize;
|
||||||
|
import org.hibernate.annotations.DynamicInsert;
|
||||||
|
import org.hibernate.annotations.DynamicUpdate;
|
||||||
import org.hibernate.annotations.Filter;
|
import org.hibernate.annotations.Filter;
|
||||||
|
import org.hibernate.annotations.ResultCheckStyle;
|
||||||
|
import org.hibernate.annotations.SQLDelete;
|
||||||
|
import org.hibernate.annotations.SQLInsert;
|
||||||
|
import org.hibernate.annotations.SQLUpdate;
|
||||||
|
import org.hibernate.annotations.Synchronize;
|
||||||
|
import org.hibernate.boot.models.HibernateAnnotations;
|
||||||
import org.hibernate.boot.models.bind.spi.BindingContext;
|
import org.hibernate.boot.models.bind.spi.BindingContext;
|
||||||
import org.hibernate.boot.models.bind.spi.BindingOptions;
|
import org.hibernate.boot.models.bind.spi.BindingOptions;
|
||||||
import org.hibernate.boot.models.bind.spi.BindingState;
|
import org.hibernate.boot.models.bind.spi.BindingState;
|
||||||
|
@ -24,6 +36,7 @@ import org.hibernate.boot.models.categorize.spi.EntityTypeMetadata;
|
||||||
import org.hibernate.boot.models.categorize.spi.JpaEventListener;
|
import org.hibernate.boot.models.categorize.spi.JpaEventListener;
|
||||||
import org.hibernate.boot.models.categorize.spi.JpaEventListenerStyle;
|
import org.hibernate.boot.models.categorize.spi.JpaEventListenerStyle;
|
||||||
import org.hibernate.boot.models.categorize.spi.MappedSuperclassTypeMetadata;
|
import org.hibernate.boot.models.categorize.spi.MappedSuperclassTypeMetadata;
|
||||||
|
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.jpa.event.internal.EntityCallback;
|
import org.hibernate.jpa.event.internal.EntityCallback;
|
||||||
|
@ -44,6 +57,8 @@ import jakarta.persistence.DiscriminatorValue;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.SharedCacheMode;
|
import jakarta.persistence.SharedCacheMode;
|
||||||
|
|
||||||
|
import static org.hibernate.boot.models.bind.ModelBindingLogging.MODEL_BINDING_MSG_LOGGER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -96,6 +111,15 @@ public abstract class EntityBinding extends IdentifiableTypeBinding {
|
||||||
bindingState.getMetadataBuildingContext().getMetadataCollector().addImport( importName, entityName );
|
bindingState.getMetadataBuildingContext().getMetadataCollector().addImport( importName, entityName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void applyCommonInformation(EntityTypeMetadata typeMetadata, PersistentClass persistentClass, BindingState bindingState) {
|
||||||
|
applyCaching( typeMetadata, persistentClass, bindingState );
|
||||||
|
applyFilters( typeMetadata, persistentClass );
|
||||||
|
applyJpaEventListeners( typeMetadata, persistentClass );
|
||||||
|
applyBatchSize( typeMetadata, persistentClass, bindingState );
|
||||||
|
applySqlCustomizations( typeMetadata, persistentClass, bindingState );
|
||||||
|
applySynchronizedTableNames( typeMetadata, persistentClass, bindingState );
|
||||||
|
}
|
||||||
|
|
||||||
protected static void applyDiscriminatorValue(
|
protected static void applyDiscriminatorValue(
|
||||||
EntityTypeMetadata typeMetadata,
|
EntityTypeMetadata typeMetadata,
|
||||||
PersistentClass persistentClass) {
|
PersistentClass persistentClass) {
|
||||||
|
@ -357,6 +381,153 @@ public abstract class EntityBinding extends IdentifiableTypeBinding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void applyBatchSize(
|
||||||
|
EntityTypeMetadata typeMetadata,
|
||||||
|
PersistentClass persistentClass,
|
||||||
|
BindingState bindingState) {
|
||||||
|
final AnnotationUsage<BatchSize> batchSizeAnnotation = typeMetadata
|
||||||
|
.getClassDetails()
|
||||||
|
.getAnnotationUsage( HibernateAnnotations.BATCH_SIZE );
|
||||||
|
if ( batchSizeAnnotation == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
persistentClass.setBatchSize( batchSizeAnnotation.getInteger( "size" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applySqlCustomizations(
|
||||||
|
EntityTypeMetadata typeMetadata,
|
||||||
|
PersistentClass persistentClass,
|
||||||
|
BindingState bindingState) {
|
||||||
|
final AnnotationUsage<DynamicInsert> dynamicInsert = typeMetadata
|
||||||
|
.getClassDetails()
|
||||||
|
.getAnnotationUsage( HibernateAnnotations.DYNAMIC_INSERT );
|
||||||
|
final AnnotationUsage<DynamicUpdate> dynamicUpdate = typeMetadata
|
||||||
|
.getClassDetails()
|
||||||
|
.getAnnotationUsage( HibernateAnnotations.DYNAMIC_UPDATE );
|
||||||
|
|
||||||
|
final List<AnnotationUsage<SQLInsert>> customInserts = typeMetadata
|
||||||
|
.getClassDetails()
|
||||||
|
.getRepeatedAnnotationUsages( HibernateAnnotations.SQL_INSERT );
|
||||||
|
final List<AnnotationUsage<SQLUpdate>> customUpdates = typeMetadata
|
||||||
|
.getClassDetails()
|
||||||
|
.getRepeatedAnnotationUsages( HibernateAnnotations.SQL_UPDATE );
|
||||||
|
final List<AnnotationUsage<SQLDelete>> customDeletes = typeMetadata
|
||||||
|
.getClassDetails()
|
||||||
|
.getRepeatedAnnotationUsages( HibernateAnnotations.SQL_DELETE );
|
||||||
|
|
||||||
|
if ( dynamicInsert != null ) {
|
||||||
|
if ( CollectionHelper.isNotEmpty( customInserts ) ) {
|
||||||
|
MODEL_BINDING_MSG_LOGGER.dynamicAndCustomInsert( persistentClass.getEntityName() );
|
||||||
|
}
|
||||||
|
persistentClass.setDynamicInsert( dynamicInsert.getBoolean( "value" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( dynamicUpdate != null ) {
|
||||||
|
if ( CollectionHelper.isNotEmpty( customUpdates ) ) {
|
||||||
|
MODEL_BINDING_MSG_LOGGER.dynamicAndCustomUpdate( persistentClass.getEntityName() );
|
||||||
|
}
|
||||||
|
persistentClass.setDynamicUpdate( dynamicUpdate.getBoolean( "value" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( customInserts )
|
||||||
|
|| CollectionHelper.isNotEmpty( customUpdates )
|
||||||
|
|| CollectionHelper.isNotEmpty( customDeletes ) ) {
|
||||||
|
final Map<String,Join> joinMap = extractJoinMap( persistentClass );
|
||||||
|
applyCustomSql(
|
||||||
|
customInserts,
|
||||||
|
persistentClass,
|
||||||
|
joinMap,
|
||||||
|
PersistentClass::setCustomSQLInsert,
|
||||||
|
Join::setCustomSQLInsert
|
||||||
|
);
|
||||||
|
applyCustomSql(
|
||||||
|
customUpdates,
|
||||||
|
persistentClass,
|
||||||
|
joinMap,
|
||||||
|
PersistentClass::setCustomSQLUpdate,
|
||||||
|
Join::setCustomSQLUpdate
|
||||||
|
);
|
||||||
|
applyCustomSql(
|
||||||
|
customDeletes,
|
||||||
|
persistentClass,
|
||||||
|
joinMap,
|
||||||
|
PersistentClass::setCustomSQLDelete,
|
||||||
|
Join::setCustomSQLDelete
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Join> extractJoinMap(PersistentClass persistentClass) {
|
||||||
|
final List<Join> joins = persistentClass.getJoins();
|
||||||
|
if ( CollectionHelper.isEmpty( joins ) ) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
final HashMap<String, Join> joinMap = CollectionHelper.mapOfSize( joins.size() );
|
||||||
|
joins.forEach( (join) -> joinMap.put( join.getTable().getName(), join ) );
|
||||||
|
return joinMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <A extends Annotation> void applyCustomSql(
|
||||||
|
List<AnnotationUsage<A>> annotationUsages,
|
||||||
|
PersistentClass persistentClass,
|
||||||
|
Map<String,Join> joinMap,
|
||||||
|
PrimaryCustomSqlInjector primaryTableInjector,
|
||||||
|
SecondaryCustomSqlInjector secondaryTableInjector) {
|
||||||
|
if ( CollectionHelper.isEmpty( annotationUsages ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
annotationUsages.forEach( annotationUsage -> {
|
||||||
|
final String tableName = annotationUsage.getString( "table" );
|
||||||
|
|
||||||
|
if ( StringHelper.isEmpty( tableName ) ) {
|
||||||
|
primaryTableInjector.injectCustomSql(
|
||||||
|
persistentClass,
|
||||||
|
annotationUsage.getString( "sql" ),
|
||||||
|
annotationUsage.getBoolean( "callable" ),
|
||||||
|
ExecuteUpdateResultCheckStyle.fromResultCheckStyle( annotationUsage.getEnum( "", ResultCheckStyle.class ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final Join join = joinMap.get( tableName );
|
||||||
|
secondaryTableInjector.injectCustomSql(
|
||||||
|
join,
|
||||||
|
annotationUsage.getString( "sql" ),
|
||||||
|
annotationUsage.getBoolean( "callable" ),
|
||||||
|
ExecuteUpdateResultCheckStyle.fromResultCheckStyle( annotationUsage.getEnum( "", ResultCheckStyle.class ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
private interface PrimaryCustomSqlInjector {
|
||||||
|
void injectCustomSql(PersistentClass persistentClass, String sql, boolean callable, ExecuteUpdateResultCheckStyle checkStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
private interface SecondaryCustomSqlInjector {
|
||||||
|
void injectCustomSql(Join join, String sql, boolean callable, ExecuteUpdateResultCheckStyle checkStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applySynchronizedTableNames(
|
||||||
|
EntityTypeMetadata typeMetadata,
|
||||||
|
PersistentClass persistentClass,
|
||||||
|
BindingState bindingState) {
|
||||||
|
final AnnotationUsage<Synchronize> usage = typeMetadata
|
||||||
|
.getClassDetails()
|
||||||
|
.getAnnotationUsage( HibernateAnnotations.SYNCHRONIZE );
|
||||||
|
if ( usage == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo : handle Synchronize#logical - for now assume it is logical
|
||||||
|
final List<String> names = usage.getList( "value" );
|
||||||
|
names.forEach( persistentClass::addSynchronizedTable );
|
||||||
|
}
|
||||||
|
|
||||||
protected void processSecondaryTables(TableReference primaryTableReference) {
|
protected void processSecondaryTables(TableReference primaryTableReference) {
|
||||||
TableHelper.bindSecondaryTables(
|
TableHelper.bindSecondaryTables(
|
||||||
this,
|
this,
|
||||||
|
|
|
@ -107,12 +107,8 @@ public class RootEntityBinding extends EntityBinding {
|
||||||
applyCacheRegions( typeMetadata, rootClass );
|
applyCacheRegions( typeMetadata, rootClass );
|
||||||
applySoftDelete( typeMetadata, rootClass, tableReference.table() );
|
applySoftDelete( typeMetadata, rootClass, tableReference.table() );
|
||||||
|
|
||||||
applyCaching( typeMetadata, rootClass, bindingState );
|
applyCommonInformation( typeMetadata, rootClass, bindingState );
|
||||||
applyFilters( typeMetadata, rootClass );
|
|
||||||
applyJpaEventListeners( typeMetadata, rootClass );
|
|
||||||
|
|
||||||
prepareAttributeBindings( tableReference.table() );
|
prepareAttributeBindings( tableReference.table() );
|
||||||
|
|
||||||
prepareSubclassBindings();
|
prepareSubclassBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,21 +40,21 @@ public class SubclassEntityBinding extends EntityBinding {
|
||||||
private final Subclass subclass;
|
private final Subclass subclass;
|
||||||
|
|
||||||
public SubclassEntityBinding(
|
public SubclassEntityBinding(
|
||||||
EntityTypeMetadata entityTypeMetadata,
|
EntityTypeMetadata typeMetadata,
|
||||||
IdentifiableTypeBinding superTypeBinding,
|
IdentifiableTypeBinding superTypeBinding,
|
||||||
EntityHierarchy.HierarchyRelation hierarchyRelation,
|
EntityHierarchy.HierarchyRelation hierarchyRelation,
|
||||||
BindingOptions bindingOptions,
|
BindingOptions bindingOptions,
|
||||||
BindingState bindingState,
|
BindingState bindingState,
|
||||||
BindingContext bindingContext) {
|
BindingContext bindingContext) {
|
||||||
super( entityTypeMetadata, superTypeBinding, hierarchyRelation, bindingOptions, bindingState, bindingContext );
|
super( typeMetadata, superTypeBinding, hierarchyRelation, bindingOptions, bindingState, bindingContext );
|
||||||
|
|
||||||
this.subclass = createSubclass();
|
this.subclass = createSubclass();
|
||||||
applyNaming( entityTypeMetadata, subclass, bindingState );
|
applyNaming( typeMetadata, subclass, bindingState );
|
||||||
bindingState.registerTypeBinding( getTypeMetadata(), this );
|
bindingState.registerTypeBinding( getTypeMetadata(), this );
|
||||||
|
|
||||||
if ( subclass instanceof TableOwner ) {
|
if ( subclass instanceof TableOwner ) {
|
||||||
final var primaryTable = TableHelper.bindPrimaryTable(
|
final var primaryTable = TableHelper.bindPrimaryTable(
|
||||||
entityTypeMetadata,
|
typeMetadata,
|
||||||
EntityHierarchy.HierarchyRelation.SUB,
|
EntityHierarchy.HierarchyRelation.SUB,
|
||||||
bindingOptions,
|
bindingOptions,
|
||||||
bindingState,
|
bindingState,
|
||||||
|
@ -64,7 +64,11 @@ public class SubclassEntityBinding extends EntityBinding {
|
||||||
( (TableOwner) subclass ).setTable( table );
|
( (TableOwner) subclass ).setTable( table );
|
||||||
}
|
}
|
||||||
|
|
||||||
applyDiscriminatorValue( getTypeMetadata(), subclass );
|
applyDiscriminatorValue( typeMetadata, subclass );
|
||||||
|
|
||||||
|
applyCommonInformation( typeMetadata, subclass, bindingState );
|
||||||
|
prepareAttributeBindings( subclass.getTable() );
|
||||||
|
prepareSubclassBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -182,10 +186,10 @@ public class SubclassEntityBinding extends EntityBinding {
|
||||||
final AnnotationUsage<ForeignKey> foreignKeyAnn = BindingHelper.getValue( joinTableAnn, "foreignKey", (AnnotationUsage<ForeignKey>) null );
|
final AnnotationUsage<ForeignKey> foreignKeyAnn = BindingHelper.getValue( joinTableAnn, "foreignKey", (AnnotationUsage<ForeignKey>) null );
|
||||||
final String foreignKeyName = foreignKeyAnn == null
|
final String foreignKeyName = foreignKeyAnn == null
|
||||||
? ""
|
? ""
|
||||||
: BindingHelper.getString( foreignKeyAnn, "name", ForeignKey.class, bindingContext );
|
: foreignKeyAnn.getString( "name" );
|
||||||
final String foreignKeyDefinition = foreignKeyAnn == null
|
final String foreignKeyDefinition = foreignKeyAnn == null
|
||||||
? ""
|
? ""
|
||||||
: BindingHelper.getString( foreignKeyAnn, "foreignKeyDefinition", ForeignKey.class, bindingContext );
|
: foreignKeyAnn.getString( "foreignKeyDefinition" );
|
||||||
|
|
||||||
final org.hibernate.mapping.ForeignKey foreignKey = targetTable.createForeignKey(
|
final org.hibernate.mapping.ForeignKey foreignKey = targetTable.createForeignKey(
|
||||||
foreignKeyName,
|
foreignKeyName,
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.boot.models.bind.internal;
|
package org.hibernate.boot.models.bind.internal;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.annotations.Comment;
|
import org.hibernate.annotations.Comment;
|
||||||
|
@ -75,7 +74,6 @@ public class TableHelper {
|
||||||
tableReference = bindPhysicalTable(
|
tableReference = bindPhysicalTable(
|
||||||
entityTypeMetadata,
|
entityTypeMetadata,
|
||||||
tableAnn,
|
tableAnn,
|
||||||
Table.class,
|
|
||||||
true,
|
true,
|
||||||
bindingOptions,
|
bindingOptions,
|
||||||
bindingState,
|
bindingState,
|
||||||
|
@ -178,7 +176,6 @@ public class TableHelper {
|
||||||
final Identifier schemaName = resolveDatabaseIdentifier(
|
final Identifier schemaName = resolveDatabaseIdentifier(
|
||||||
secondaryTableAnn,
|
secondaryTableAnn,
|
||||||
"schema",
|
"schema",
|
||||||
jakarta.persistence.SecondaryTable.class,
|
|
||||||
bindingOptions.getDefaultSchemaName(),
|
bindingOptions.getDefaultSchemaName(),
|
||||||
QuotedIdentifierTarget.SCHEMA_NAME,
|
QuotedIdentifierTarget.SCHEMA_NAME,
|
||||||
bindingOptions,
|
bindingOptions,
|
||||||
|
@ -188,7 +185,6 @@ public class TableHelper {
|
||||||
final Identifier catalogName = resolveDatabaseIdentifier(
|
final Identifier catalogName = resolveDatabaseIdentifier(
|
||||||
secondaryTableAnn,
|
secondaryTableAnn,
|
||||||
"catalog",
|
"catalog",
|
||||||
jakarta.persistence.SecondaryTable.class,
|
|
||||||
bindingOptions.getDefaultCatalogName(),
|
bindingOptions.getDefaultCatalogName(),
|
||||||
QuotedIdentifierTarget.CATALOG_NAME,
|
QuotedIdentifierTarget.CATALOG_NAME,
|
||||||
bindingOptions,
|
bindingOptions,
|
||||||
|
@ -249,7 +245,7 @@ public class TableHelper {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// either an explicit or implicit @Table
|
// either an explicit or implicit @Table
|
||||||
tableReference = bindPhysicalTable( type, tableAnn, annotationType, true, bindingOptions, bindingState, bindingContext );
|
tableReference = bindPhysicalTable( type, tableAnn, true, bindingOptions, bindingState, bindingContext );
|
||||||
}
|
}
|
||||||
return tableReference;
|
return tableReference;
|
||||||
}
|
}
|
||||||
|
@ -281,7 +277,7 @@ public class TableHelper {
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
logicalName.getCanonicalName(),
|
logicalName.getCanonicalName(),
|
||||||
BindingHelper.getString( subselectAnn, "value", Subselect.class, bindingContext ),
|
subselectAnn.getString( "value" ),
|
||||||
true,
|
true,
|
||||||
bindingState.getMetadataBuildingContext()
|
bindingState.getMetadataBuildingContext()
|
||||||
)
|
)
|
||||||
|
@ -291,13 +287,12 @@ public class TableHelper {
|
||||||
private static <A extends Annotation> PhysicalTableReference bindPhysicalTable(
|
private static <A extends Annotation> PhysicalTableReference bindPhysicalTable(
|
||||||
EntityTypeMetadata type,
|
EntityTypeMetadata type,
|
||||||
AnnotationUsage<A> tableAnn,
|
AnnotationUsage<A> tableAnn,
|
||||||
Class<A> annotationType,
|
|
||||||
boolean isPrimary,
|
boolean isPrimary,
|
||||||
BindingOptions bindingOptions,
|
BindingOptions bindingOptions,
|
||||||
BindingState bindingState,
|
BindingState bindingState,
|
||||||
BindingContext bindingContext) {
|
BindingContext bindingContext) {
|
||||||
if ( tableAnn != null ) {
|
if ( tableAnn != null ) {
|
||||||
return bindExplicitPhysicalTable( type, tableAnn, annotationType, isPrimary, bindingOptions, bindingState, bindingContext );
|
return bindExplicitPhysicalTable( type, tableAnn, isPrimary, bindingOptions, bindingState, bindingContext );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return bindImplicitPhysicalTable( type, isPrimary, bindingOptions, bindingState, bindingContext );
|
return bindImplicitPhysicalTable( type, isPrimary, bindingOptions, bindingState, bindingContext );
|
||||||
|
@ -307,7 +302,6 @@ public class TableHelper {
|
||||||
private static <A extends Annotation> PhysicalTable bindExplicitPhysicalTable(
|
private static <A extends Annotation> PhysicalTable bindExplicitPhysicalTable(
|
||||||
EntityTypeMetadata type,
|
EntityTypeMetadata type,
|
||||||
AnnotationUsage<A> tableAnn,
|
AnnotationUsage<A> tableAnn,
|
||||||
Class<A> annotationType,
|
|
||||||
boolean isPrimary,
|
boolean isPrimary,
|
||||||
BindingOptions bindingOptions,
|
BindingOptions bindingOptions,
|
||||||
BindingState bindingState,
|
BindingState bindingState,
|
||||||
|
@ -316,7 +310,6 @@ public class TableHelper {
|
||||||
final Identifier logicalSchemaName = resolveDatabaseIdentifier(
|
final Identifier logicalSchemaName = resolveDatabaseIdentifier(
|
||||||
tableAnn,
|
tableAnn,
|
||||||
"schema",
|
"schema",
|
||||||
annotationType,
|
|
||||||
bindingOptions.getDefaultSchemaName(),
|
bindingOptions.getDefaultSchemaName(),
|
||||||
QuotedIdentifierTarget.SCHEMA_NAME,
|
QuotedIdentifierTarget.SCHEMA_NAME,
|
||||||
bindingOptions,
|
bindingOptions,
|
||||||
|
@ -326,7 +319,6 @@ public class TableHelper {
|
||||||
final Identifier logicalCatalogName = resolveDatabaseIdentifier(
|
final Identifier logicalCatalogName = resolveDatabaseIdentifier(
|
||||||
tableAnn,
|
tableAnn,
|
||||||
"catalog",
|
"catalog",
|
||||||
annotationType,
|
|
||||||
bindingOptions.getDefaultCatalogName(),
|
bindingOptions.getDefaultCatalogName(),
|
||||||
QuotedIdentifierTarget.CATALOG_NAME,
|
QuotedIdentifierTarget.CATALOG_NAME,
|
||||||
bindingOptions,
|
bindingOptions,
|
||||||
|
@ -412,7 +404,6 @@ public class TableHelper {
|
||||||
final Identifier logicalSchemaName = resolveDatabaseIdentifier(
|
final Identifier logicalSchemaName = resolveDatabaseIdentifier(
|
||||||
tableAnn,
|
tableAnn,
|
||||||
"schema",
|
"schema",
|
||||||
Table.class,
|
|
||||||
bindingOptions.getDefaultSchemaName(),
|
bindingOptions.getDefaultSchemaName(),
|
||||||
QuotedIdentifierTarget.SCHEMA_NAME,
|
QuotedIdentifierTarget.SCHEMA_NAME,
|
||||||
bindingOptions,
|
bindingOptions,
|
||||||
|
@ -422,7 +413,6 @@ public class TableHelper {
|
||||||
final Identifier logicalCatalogName = resolveDatabaseIdentifier(
|
final Identifier logicalCatalogName = resolveDatabaseIdentifier(
|
||||||
tableAnn,
|
tableAnn,
|
||||||
"catalog",
|
"catalog",
|
||||||
Table.class,
|
|
||||||
bindingOptions.getDefaultCatalogName(),
|
bindingOptions.getDefaultCatalogName(),
|
||||||
QuotedIdentifierTarget.CATALOG_NAME,
|
QuotedIdentifierTarget.CATALOG_NAME,
|
||||||
bindingOptions,
|
bindingOptions,
|
||||||
|
@ -486,23 +476,24 @@ public class TableHelper {
|
||||||
private static <A extends Annotation> Identifier resolveDatabaseIdentifier(
|
private static <A extends Annotation> Identifier resolveDatabaseIdentifier(
|
||||||
AnnotationUsage<A> annotationUsage,
|
AnnotationUsage<A> annotationUsage,
|
||||||
String attributeName,
|
String attributeName,
|
||||||
Class<A> annotationType,
|
|
||||||
Identifier fallback,
|
Identifier fallback,
|
||||||
QuotedIdentifierTarget target,
|
QuotedIdentifierTarget target,
|
||||||
BindingOptions bindingOptions,
|
BindingOptions bindingOptions,
|
||||||
BindingState bindingState,
|
@SuppressWarnings("unused") BindingState bindingState,
|
||||||
BindingContext bindingContext) {
|
BindingContext bindingContext) {
|
||||||
final String explicit = BindingHelper.getStringOrNull( annotationUsage, attributeName );
|
if ( annotationUsage == null ) {
|
||||||
if ( StringHelper.isNotEmpty( explicit ) ) {
|
|
||||||
return BindingHelper.toIdentifier( explicit, target, bindingOptions, jdbcEnvironment( bindingContext ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( fallback != null ) {
|
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
final String explicitValue = annotationUsage.getString( attributeName );
|
||||||
final String defaultValue = BindingHelper.getDefaultValue( attributeName, annotationType, bindingContext );
|
if ( StringHelper.isEmpty( explicitValue ) ) {
|
||||||
return BindingHelper.toIdentifier(defaultValue, target, bindingOptions, jdbcEnvironment( bindingContext ) );
|
return fallback;
|
||||||
|
}
|
||||||
|
return BindingHelper.toIdentifier(
|
||||||
|
explicitValue,
|
||||||
|
target,
|
||||||
|
bindingOptions,
|
||||||
|
jdbcEnvironment( bindingContext )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AnnotationUsage<Comment> findCommentAnnotation(
|
private static AnnotationUsage<Comment> findCommentAnnotation(
|
||||||
|
|
|
@ -8,14 +8,7 @@ package org.hibernate.boot.models.categorize;
|
||||||
|
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
|
|
||||||
import org.jboss.logging.BasicLogger;
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.jboss.logging.annotations.LogMessage;
|
|
||||||
import org.jboss.logging.annotations.Message;
|
|
||||||
import org.jboss.logging.annotations.MessageLogger;
|
|
||||||
import org.jboss.logging.annotations.ValidIdRange;
|
|
||||||
|
|
||||||
import static org.jboss.logging.Logger.Level.INFO;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* todo : find the proper min/max id range
|
* todo : find the proper min/max id range
|
||||||
|
@ -23,19 +16,8 @@ import static org.jboss.logging.Logger.Level.INFO;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
@MessageLogger( projectCode = "HHH" )
|
public interface ModelCategorizationLogging {
|
||||||
@ValidIdRange( min = 999901, max = 999999 )
|
|
||||||
public interface ModelCategorizationLogging extends BasicLogger {
|
|
||||||
String NAME = "org.hibernate.models.orm";
|
String NAME = "org.hibernate.models.orm";
|
||||||
|
|
||||||
Logger MODEL_CATEGORIZATION_LOGGER = Logger.getLogger( NAME );
|
Logger MODEL_CATEGORIZATION_LOGGER = Logger.getLogger( NAME );
|
||||||
ModelCategorizationLogging MODEL_CATEGORIZATION_MSG_LOGGER = Logger.getMessageLogger( ModelCategorizationLogging.class, NAME );
|
|
||||||
|
|
||||||
@LogMessage(level = INFO)
|
|
||||||
@Message( id = 999901, value = "Entity `%s` used both @DynamicInsert and @SQLInsert" )
|
|
||||||
void dynamicAndCustomInsert(String entityName);
|
|
||||||
|
|
||||||
@LogMessage(level = INFO)
|
|
||||||
@Message( id = 999902, value = "Entity `%s` used both @DynamicUpdate and @SQLUpdate" )
|
|
||||||
void dynamicAndCustomUpdate(String entityName);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,13 +28,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class SimpleBindingCoordinatorTests {
|
@ServiceRegistry( settingProviders = @SettingProvider(
|
||||||
@Test
|
|
||||||
@ServiceRegistry( settingProviders = @SettingProvider(
|
|
||||||
settingName = AvailableSettings.PHYSICAL_NAMING_STRATEGY,
|
settingName = AvailableSettings.PHYSICAL_NAMING_STRATEGY,
|
||||||
provider = CustomNamingStrategyProvider.class
|
provider = CustomNamingStrategyProvider.class
|
||||||
) )
|
) )
|
||||||
void testIt(ServiceRegistryScope scope) {
|
public class SimpleBindingCoordinatorTests {
|
||||||
|
@Test
|
||||||
|
void testCollectorState(ServiceRegistryScope scope) {
|
||||||
BindingTestingHelper.checkDomainModel(
|
BindingTestingHelper.checkDomainModel(
|
||||||
(context) -> {
|
(context) -> {
|
||||||
final var bindingState = context.getBindingState();
|
final var bindingState = context.getBindingState();
|
||||||
|
@ -75,15 +75,17 @@ public class SimpleBindingCoordinatorTests {
|
||||||
assertThat( namespaceItr.hasNext() ).isFalse();
|
assertThat( namespaceItr.hasNext() ).isFalse();
|
||||||
assertThat( namespace1.getTables() ).hasSize( 1 );
|
assertThat( namespace1.getTables() ).hasSize( 1 );
|
||||||
assertThat( namespace2.getTables() ).hasSize( 1 );
|
assertThat( namespace2.getTables() ).hasSize( 1 );
|
||||||
|
},
|
||||||
|
scope.getRegistry(),
|
||||||
|
SimpleEntity.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAttributes(ServiceRegistryScope scope) {
|
||||||
|
BindingTestingHelper.checkDomainModel(
|
||||||
|
(context) -> {
|
||||||
final RootClass entityBinding = (RootClass) context.getMetadataCollector().getEntityBinding( SimpleEntity.class.getName() );
|
final RootClass entityBinding = (RootClass) context.getMetadataCollector().getEntityBinding( SimpleEntity.class.getName() );
|
||||||
assertThat( entityBinding.isCached() ).isFalse();
|
|
||||||
final Column softDeleteColumn = entityBinding.getSoftDeleteColumn();
|
|
||||||
assertThat( softDeleteColumn ).isNotNull();
|
|
||||||
assertThat( softDeleteColumn.getName() ).isEqualTo( "ACTIVE" );
|
|
||||||
assertThat( entityBinding.getFilters() ).hasSize( 1 );
|
|
||||||
assertThat( entityBinding.getCacheRegionName() ).isEqualTo( "my-region" );
|
|
||||||
assertThat( entityBinding.getCacheConcurrencyStrategy() ).isEqualTo( CacheConcurrencyStrategy.READ_ONLY.toAccessType().getExternalName() );
|
|
||||||
|
|
||||||
final Property id = entityBinding.getProperty( "id" );
|
final Property id = entityBinding.getProperty( "id" );
|
||||||
assertThat( id.getValue().getTable().getName() ).isEqualTo( "SIMPLETONS" );
|
assertThat( id.getValue().getTable().getName() ).isEqualTo( "SIMPLETONS" );
|
||||||
|
@ -125,4 +127,74 @@ public class SimpleBindingCoordinatorTests {
|
||||||
SimpleEntity.class
|
SimpleEntity.class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCaching(ServiceRegistryScope scope) {
|
||||||
|
BindingTestingHelper.checkDomainModel(
|
||||||
|
(context) -> {
|
||||||
|
final RootClass entityBinding = (RootClass) context.getMetadataCollector().getEntityBinding( SimpleEntity.class.getName() );
|
||||||
|
assertThat( entityBinding.isCached() ).isFalse();
|
||||||
|
assertThat( entityBinding.getCacheRegionName() ).isEqualTo( "my-region" );
|
||||||
|
assertThat( entityBinding.getCacheConcurrencyStrategy() ).isEqualTo( CacheConcurrencyStrategy.READ_ONLY.toAccessType().getExternalName() );
|
||||||
|
|
||||||
|
},
|
||||||
|
scope.getRegistry(),
|
||||||
|
SimpleEntity.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBatchSize(ServiceRegistryScope scope) {
|
||||||
|
BindingTestingHelper.checkDomainModel(
|
||||||
|
(context) -> {
|
||||||
|
final RootClass entityBinding = (RootClass) context.getMetadataCollector().getEntityBinding( SimpleEntity.class.getName() );
|
||||||
|
assertThat( entityBinding.getBatchSize() ).isEqualTo( 32 );
|
||||||
|
},
|
||||||
|
scope.getRegistry(),
|
||||||
|
SimpleEntity.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSoftDelete(ServiceRegistryScope scope) {
|
||||||
|
BindingTestingHelper.checkDomainModel(
|
||||||
|
(context) -> {
|
||||||
|
final RootClass entityBinding = (RootClass) context.getMetadataCollector().getEntityBinding( SimpleEntity.class.getName() );
|
||||||
|
|
||||||
|
final Column softDeleteColumn = entityBinding.getSoftDeleteColumn();
|
||||||
|
assertThat( softDeleteColumn ).isNotNull();
|
||||||
|
assertThat( softDeleteColumn.getName() ).isEqualTo( "ACTIVE" );
|
||||||
|
|
||||||
|
},
|
||||||
|
scope.getRegistry(),
|
||||||
|
SimpleEntity.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSynchronization(ServiceRegistryScope scope) {
|
||||||
|
BindingTestingHelper.checkDomainModel(
|
||||||
|
(context) -> {
|
||||||
|
final RootClass entityBinding = (RootClass) context.getMetadataCollector().getEntityBinding( SimpleEntity.class.getName() );
|
||||||
|
|
||||||
|
assertThat( entityBinding.getSynchronizedTables() ).hasSize( 1 );
|
||||||
|
|
||||||
|
assertThat( entityBinding.getFilters() ).hasSize( 1 );
|
||||||
|
},
|
||||||
|
scope.getRegistry(),
|
||||||
|
SimpleEntity.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilters(ServiceRegistryScope scope) {
|
||||||
|
BindingTestingHelper.checkDomainModel(
|
||||||
|
(context) -> {
|
||||||
|
final RootClass entityBinding = (RootClass) context.getMetadataCollector().getEntityBinding( SimpleEntity.class.getName() );
|
||||||
|
assertThat( entityBinding.getFilters() ).hasSize( 1 );
|
||||||
|
},
|
||||||
|
scope.getRegistry(),
|
||||||
|
SimpleEntity.class
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.boot.models.bind;
|
package org.hibernate.orm.test.boot.models.bind;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.BatchSize;
|
||||||
import org.hibernate.annotations.Cache;
|
import org.hibernate.annotations.Cache;
|
||||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||||
import org.hibernate.annotations.Filter;
|
import org.hibernate.annotations.Filter;
|
||||||
|
@ -13,6 +14,7 @@ import org.hibernate.annotations.FilterDef;
|
||||||
import org.hibernate.annotations.ParamDef;
|
import org.hibernate.annotations.ParamDef;
|
||||||
import org.hibernate.annotations.SoftDelete;
|
import org.hibernate.annotations.SoftDelete;
|
||||||
import org.hibernate.annotations.SoftDeleteType;
|
import org.hibernate.annotations.SoftDeleteType;
|
||||||
|
import org.hibernate.annotations.Synchronize;
|
||||||
import org.hibernate.annotations.TenantId;
|
import org.hibernate.annotations.TenantId;
|
||||||
|
|
||||||
import jakarta.persistence.Basic;
|
import jakarta.persistence.Basic;
|
||||||
|
@ -39,6 +41,8 @@ import jakarta.persistence.Version;
|
||||||
@SoftDelete(strategy = SoftDeleteType.ACTIVE)
|
@SoftDelete(strategy = SoftDeleteType.ACTIVE)
|
||||||
@Cacheable(false)
|
@Cacheable(false)
|
||||||
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region = "my-region")
|
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region = "my-region")
|
||||||
|
@BatchSize(size = 32)
|
||||||
|
@Synchronize("some_other_table")
|
||||||
public class SimpleEntity {
|
public class SimpleEntity {
|
||||||
@Id
|
@Id
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
Loading…
Reference in New Issue