some code and warning cleanups in org.hibernate.boot
This commit is contained in:
parent
04b8d80125
commit
6612868d29
|
@ -24,7 +24,6 @@ import org.hibernate.event.spi.PreUpdateEventListener;
|
||||||
import org.hibernate.event.spi.PreUpsertEvent;
|
import org.hibernate.event.spi.PreUpsertEvent;
|
||||||
import org.hibernate.event.spi.PreUpsertEventListener;
|
import org.hibernate.event.spi.PreUpsertEventListener;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
|
||||||
import org.hibernate.metamodel.RepresentationMode;
|
import org.hibernate.metamodel.RepresentationMode;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
@ -33,10 +32,12 @@ import org.jboss.logging.Logger;
|
||||||
import jakarta.validation.ConstraintViolation;
|
import jakarta.validation.ConstraintViolation;
|
||||||
import jakarta.validation.ConstraintViolationException;
|
import jakarta.validation.ConstraintViolationException;
|
||||||
import jakarta.validation.TraversableResolver;
|
import jakarta.validation.TraversableResolver;
|
||||||
import jakarta.validation.Validation;
|
|
||||||
import jakarta.validation.Validator;
|
import jakarta.validation.Validator;
|
||||||
import jakarta.validation.ValidatorFactory;
|
import jakarta.validation.ValidatorFactory;
|
||||||
|
|
||||||
|
import static jakarta.validation.Validation.buildDefaultValidatorFactory;
|
||||||
|
import static org.hibernate.internal.util.collections.CollectionHelper.setOfSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event listener used to enable Bean Validation for insert/update/delete events.
|
* Event listener used to enable Bean Validation for insert/update/delete events.
|
||||||
*
|
*
|
||||||
|
@ -71,8 +72,7 @@ public class BeanValidationEventListener
|
||||||
|
|
||||||
public void initialize(Map<String,Object> settings, ClassLoaderService classLoaderService) {
|
public void initialize(Map<String,Object> settings, ClassLoaderService classLoaderService) {
|
||||||
if ( !initialized ) {
|
if ( !initialized ) {
|
||||||
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
init( buildDefaultValidatorFactory(), settings, classLoaderService );
|
||||||
init( factory, settings, classLoaderService );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,15 +138,15 @@ public class BeanValidationEventListener
|
||||||
final Class<?>[] groups = groupsPerOperation.get( operation );
|
final Class<?>[] groups = groupsPerOperation.get( operation );
|
||||||
if ( groups.length > 0 ) {
|
if ( groups.length > 0 ) {
|
||||||
final Set<ConstraintViolation<T>> constraintViolations = validator.validate( object, groups );
|
final Set<ConstraintViolation<T>> constraintViolations = validator.validate( object, groups );
|
||||||
if ( constraintViolations.size() > 0 ) {
|
if ( !constraintViolations.isEmpty() ) {
|
||||||
Set<ConstraintViolation<?>> propagatedViolations = CollectionHelper.setOfSize( constraintViolations.size() );
|
final Set<ConstraintViolation<?>> propagatedViolations = setOfSize( constraintViolations.size() );
|
||||||
Set<String> classNames = new HashSet<>();
|
final Set<String> classNames = new HashSet<>();
|
||||||
for ( ConstraintViolation<?> violation : constraintViolations ) {
|
for ( ConstraintViolation<?> violation : constraintViolations ) {
|
||||||
LOG.trace( violation );
|
LOG.trace( violation );
|
||||||
propagatedViolations.add( violation );
|
propagatedViolations.add( violation );
|
||||||
classNames.add( violation.getLeafBean().getClass().getName() );
|
classNames.add( violation.getLeafBean().getClass().getName() );
|
||||||
}
|
}
|
||||||
StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
builder.append( "Validation failed for classes " );
|
builder.append( "Validation failed for classes " );
|
||||||
builder.append( classNames );
|
builder.append( classNames );
|
||||||
builder.append( " during " );
|
builder.append( " during " );
|
||||||
|
@ -154,20 +154,18 @@ public class BeanValidationEventListener
|
||||||
builder.append( " time for groups " );
|
builder.append( " time for groups " );
|
||||||
builder.append( toString( groups ) );
|
builder.append( toString( groups ) );
|
||||||
builder.append( "\nList of constraint violations:[\n" );
|
builder.append( "\nList of constraint violations:[\n" );
|
||||||
for (ConstraintViolation<?> violation : constraintViolations) {
|
for ( ConstraintViolation<?> violation : constraintViolations ) {
|
||||||
builder.append( "\t" ).append( violation.toString() ).append("\n");
|
builder.append( "\t" ).append( violation.toString() ).append("\n");
|
||||||
}
|
}
|
||||||
builder.append( "]" );
|
builder.append( "]" );
|
||||||
|
|
||||||
throw new ConstraintViolationException(
|
throw new ConstraintViolationException( builder.toString(), propagatedViolations );
|
||||||
builder.toString(), propagatedViolations
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toString(Class<?>[] groups) {
|
private String toString(Class<?>[] groups) {
|
||||||
StringBuilder toString = new StringBuilder( "[" );
|
final StringBuilder toString = new StringBuilder( "[" );
|
||||||
for ( Class<?> group : groups ) {
|
for ( Class<?> group : groups ) {
|
||||||
toString.append( group.getName() ).append( ", " );
|
toString.append( group.getName() ).append( ", " );
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,11 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.ClassLoaderAccess;
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
|
||||||
|
|
||||||
import jakarta.validation.groups.Default;
|
import jakarta.validation.groups.Default;
|
||||||
|
|
||||||
|
import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
|
@ -29,27 +30,25 @@ public class GroupsPerOperation {
|
||||||
private static final Class<?>[] DEFAULT_GROUPS = new Class<?>[] { Default.class };
|
private static final Class<?>[] DEFAULT_GROUPS = new Class<?>[] { Default.class };
|
||||||
private static final Class<?>[] EMPTY_GROUPS = new Class<?>[] { };
|
private static final Class<?>[] EMPTY_GROUPS = new Class<?>[] { };
|
||||||
|
|
||||||
private final Map<Operation, Class<?>[]> groupsPerOperation = CollectionHelper.mapOfSize( 4 );
|
private final Map<Operation, Class<?>[]> groupsPerOperation = mapOfSize( 4 );
|
||||||
|
|
||||||
private GroupsPerOperation() {
|
private GroupsPerOperation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GroupsPerOperation from(Map settings, ClassLoaderAccess classLoaderAccess) {
|
public static GroupsPerOperation from(Map<String,Object> settings, ClassLoaderAccess classLoaderAccess) {
|
||||||
GroupsPerOperation groupsPerOperation = new GroupsPerOperation();
|
final GroupsPerOperation groupsPerOperation = new GroupsPerOperation();
|
||||||
|
|
||||||
applyOperationGrouping( groupsPerOperation, Operation.INSERT, settings, classLoaderAccess );
|
applyOperationGrouping( groupsPerOperation, Operation.INSERT, settings, classLoaderAccess );
|
||||||
applyOperationGrouping( groupsPerOperation, Operation.UPDATE, settings, classLoaderAccess );
|
applyOperationGrouping( groupsPerOperation, Operation.UPDATE, settings, classLoaderAccess );
|
||||||
applyOperationGrouping( groupsPerOperation, Operation.DELETE, settings, classLoaderAccess );
|
applyOperationGrouping( groupsPerOperation, Operation.DELETE, settings, classLoaderAccess );
|
||||||
applyOperationGrouping( groupsPerOperation, Operation.UPSERT, settings, classLoaderAccess );
|
applyOperationGrouping( groupsPerOperation, Operation.UPSERT, settings, classLoaderAccess );
|
||||||
applyOperationGrouping( groupsPerOperation, Operation.DDL, settings, classLoaderAccess );
|
applyOperationGrouping( groupsPerOperation, Operation.DDL, settings, classLoaderAccess );
|
||||||
|
|
||||||
return groupsPerOperation;
|
return groupsPerOperation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void applyOperationGrouping(
|
private static void applyOperationGrouping(
|
||||||
GroupsPerOperation groupsPerOperation,
|
GroupsPerOperation groupsPerOperation,
|
||||||
Operation operation,
|
Operation operation,
|
||||||
Map settings,
|
Map<String,Object> settings,
|
||||||
ClassLoaderAccess classLoaderAccess) {
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
groupsPerOperation.groupsPerOperation.put(
|
groupsPerOperation.groupsPerOperation.put(
|
||||||
operation,
|
operation,
|
||||||
|
@ -57,7 +56,8 @@ public class GroupsPerOperation {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Class<?>[] buildGroupsForOperation(Operation operation, Map settings, ClassLoaderAccess classLoaderAccess) {
|
public static Class<?>[] buildGroupsForOperation(
|
||||||
|
Operation operation, Map<String,Object> settings, ClassLoaderAccess classLoaderAccess) {
|
||||||
Object property = settings.get( operation.getJakartaGroupPropertyName() );
|
Object property = settings.get( operation.getJakartaGroupPropertyName() );
|
||||||
if ( property == null ) {
|
if ( property == null ) {
|
||||||
property = settings.get( operation.getGroupPropertyName() );
|
property = settings.get( operation.getGroupPropertyName() );
|
||||||
|
@ -67,21 +67,20 @@ public class GroupsPerOperation {
|
||||||
return operation == Operation.DELETE ? EMPTY_GROUPS : DEFAULT_GROUPS;
|
return operation == Operation.DELETE ? EMPTY_GROUPS : DEFAULT_GROUPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( property instanceof Class<?>[] ) {
|
if ( property instanceof Class<?>[] classes ) {
|
||||||
return (Class<?>[]) property;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( property instanceof String ) {
|
if ( property instanceof String string ) {
|
||||||
String stringProperty = (String) property;
|
final String[] groupNames = StringHelper.split( ",", string );
|
||||||
String[] groupNames = StringHelper.split( ",", stringProperty );
|
|
||||||
if ( groupNames.length == 1 && groupNames[0].isEmpty() ) {
|
if ( groupNames.length == 1 && groupNames[0].isEmpty() ) {
|
||||||
return EMPTY_GROUPS;
|
return EMPTY_GROUPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Class<?>> groupsList = new ArrayList<>(groupNames.length);
|
final List<Class<?>> groupsList = new ArrayList<>( groupNames.length );
|
||||||
for (String groupName : groupNames) {
|
for ( String groupName : groupNames ) {
|
||||||
String cleanedGroupName = groupName.trim();
|
final String cleanedGroupName = groupName.trim();
|
||||||
if ( cleanedGroupName.length() > 0) {
|
if ( !cleanedGroupName.isEmpty() ) {
|
||||||
try {
|
try {
|
||||||
groupsList.add( classLoaderAccess.classForName( cleanedGroupName ) );
|
groupsList.add( classLoaderAccess.classForName( cleanedGroupName ) );
|
||||||
}
|
}
|
||||||
|
@ -90,11 +89,13 @@ public class GroupsPerOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return groupsList.toArray( new Class<?>[groupsList.size()] );
|
return groupsList.toArray( new Class<?>[0] );
|
||||||
}
|
}
|
||||||
|
|
||||||
//null is bad and excluded by instanceof => exception is raised
|
//null is bad and excluded by instanceof => exception is raised
|
||||||
throw new HibernateException( JAKARTA_JPA_GROUP_PREFIX + operation.getJakartaGroupPropertyName() + " is of unknown type: String or Class<?>[] only");
|
throw new HibernateException( JAKARTA_JPA_GROUP_PREFIX
|
||||||
|
+ operation.getJakartaGroupPropertyName()
|
||||||
|
+ " is of unknown type: String or Class<?>[] only");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<?>[] get(Operation operation) {
|
public Class<?>[] get(Operation operation) {
|
||||||
|
|
|
@ -18,7 +18,6 @@ import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.ComponentType;
|
import org.hibernate.type.ComponentType;
|
||||||
import org.hibernate.type.CompositeType;
|
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -27,9 +26,8 @@ import jakarta.validation.TraversableResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use Hibernate metadata to ignore cascade on entities.
|
* Use Hibernate metadata to ignore cascade on entities.
|
||||||
* cascade on embeddable objects or collection of embeddable objects are accepted
|
* Cascade on embeddable objects or collection of embeddable objects are accepted
|
||||||
*
|
* Also use Hibernate's native {@link Hibernate#isInitialized} method call.
|
||||||
* Also use Hibernate's native isInitialized method call.
|
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
|
@ -40,44 +38,43 @@ public class HibernateTraversableResolver implements TraversableResolver {
|
||||||
EntityPersister persister,
|
EntityPersister persister,
|
||||||
ConcurrentHashMap<EntityPersister, Set<String>> associationsPerEntityPersister,
|
ConcurrentHashMap<EntityPersister, Set<String>> associationsPerEntityPersister,
|
||||||
SessionFactoryImplementor factory) {
|
SessionFactoryImplementor factory) {
|
||||||
this.associations = associationsPerEntityPersister.get( persister );
|
associations = associationsPerEntityPersister.get( persister );
|
||||||
if (this.associations == null) {
|
if ( associations == null ) {
|
||||||
this.associations = new HashSet<>();
|
associations = new HashSet<>();
|
||||||
addAssociationsToTheSetForAllProperties( persister.getPropertyNames(), persister.getPropertyTypes(), "", factory );
|
addAssociationsToTheSetForAllProperties( persister.getPropertyNames(), persister.getPropertyTypes(), "", factory );
|
||||||
associationsPerEntityPersister.put( persister, associations );
|
associationsPerEntityPersister.put( persister, associations );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAssociationsToTheSetForAllProperties(String[] names, Type[] types, String prefix, SessionFactoryImplementor factory) {
|
private void addAssociationsToTheSetForAllProperties(
|
||||||
|
String[] names, Type[] types, String prefix, SessionFactoryImplementor factory) {
|
||||||
final int length = names.length;
|
final int length = names.length;
|
||||||
for( int index = 0 ; index < length; index++ ) {
|
for( int index = 0 ; index < length; index++ ) {
|
||||||
addAssociationsToTheSetForOneProperty( names[index], types[index], prefix, factory );
|
addAssociationsToTheSetForOneProperty( names[index], types[index], prefix, factory );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAssociationsToTheSetForOneProperty(String name, Type type, String prefix, SessionFactoryImplementor factory) {
|
private void addAssociationsToTheSetForOneProperty(
|
||||||
|
String name, Type type, String prefix, SessionFactoryImplementor factory) {
|
||||||
if ( type instanceof CollectionType ) {
|
if ( type instanceof CollectionType collectionType ) {
|
||||||
CollectionType collType = (CollectionType) type;
|
addAssociationsToTheSetForOneProperty( name, collectionType.getElementType( factory ), prefix, factory );
|
||||||
Type assocType = collType.getElementType( factory );
|
|
||||||
addAssociationsToTheSetForOneProperty(name, assocType, prefix, factory);
|
|
||||||
}
|
}
|
||||||
//ToOne association
|
//ToOne association
|
||||||
else if ( type instanceof EntityType || type instanceof AnyType ) {
|
else if ( type instanceof EntityType || type instanceof AnyType ) {
|
||||||
associations.add( prefix + name );
|
associations.add( prefix + name );
|
||||||
}
|
}
|
||||||
else if ( type instanceof ComponentType ) {
|
else if ( type instanceof ComponentType componentType ) {
|
||||||
ComponentType componentType = (ComponentType) type;
|
|
||||||
addAssociationsToTheSetForAllProperties(
|
addAssociationsToTheSetForAllProperties(
|
||||||
componentType.getPropertyNames(),
|
componentType.getPropertyNames(),
|
||||||
componentType.getSubtypes(),
|
componentType.getSubtypes(),
|
||||||
( prefix.isEmpty() ? name : prefix + name ) + '.',
|
( prefix.isEmpty() ? name : prefix + name ) + '.',
|
||||||
factory);
|
factory
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStringBasedPath(Path.Node traversableProperty, Path pathToTraversableObject) {
|
private String getStringBasedPath(Path.Node traversableProperty, Path pathToTraversableObject) {
|
||||||
StringBuilder path = new StringBuilder( );
|
final StringBuilder path = new StringBuilder( );
|
||||||
for ( Path.Node node : pathToTraversableObject ) {
|
for ( Path.Node node : pathToTraversableObject ) {
|
||||||
if (node.getName() != null) {
|
if (node.getName() != null) {
|
||||||
path.append( node.getName() ).append( '.' );
|
path.append( node.getName() ).append( '.' );
|
||||||
|
@ -89,7 +86,6 @@ public class HibernateTraversableResolver implements TraversableResolver {
|
||||||
+ path );
|
+ path );
|
||||||
}
|
}
|
||||||
path.append( traversableProperty.getName() );
|
path.append( traversableProperty.getName() );
|
||||||
|
|
||||||
return path.toString();
|
return path.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +96,7 @@ public class HibernateTraversableResolver implements TraversableResolver {
|
||||||
ElementType elementType) {
|
ElementType elementType) {
|
||||||
//lazy, don't load
|
//lazy, don't load
|
||||||
return Hibernate.isInitialized( traversableObject )
|
return Hibernate.isInitialized( traversableObject )
|
||||||
&& Hibernate.isPropertyInitialized( traversableObject, traversableProperty.getName() );
|
&& Hibernate.isPropertyInitialized( traversableObject, traversableProperty.getName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCascadable(Object traversableObject,
|
public boolean isCascadable(Object traversableObject,
|
||||||
|
@ -108,7 +104,6 @@ public class HibernateTraversableResolver implements TraversableResolver {
|
||||||
Class<?> rootBeanType,
|
Class<?> rootBeanType,
|
||||||
Path pathToTraversableObject,
|
Path pathToTraversableObject,
|
||||||
ElementType elementType) {
|
ElementType elementType) {
|
||||||
String path = getStringBasedPath( traversableProperty, pathToTraversableObject );
|
return !associations.contains( getStringBasedPath( traversableProperty, pathToTraversableObject ) );
|
||||||
return ! associations.contains(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,10 +279,9 @@ class TypeSafeActivator {
|
||||||
final long min = minConstraint.getAnnotation().value();
|
final long min = minConstraint.getAnnotation().value();
|
||||||
|
|
||||||
for ( Selectable selectable : property.getSelectables() ) {
|
for ( Selectable selectable : property.getSelectables() ) {
|
||||||
if ( selectable instanceof Column ) {
|
if ( selectable instanceof Column column ) {
|
||||||
Column col = (Column) selectable;
|
final String checkConstraint = column.getQuotedName( dialect ) + ">=" + min;
|
||||||
String checkConstraint = col.getQuotedName(dialect) + ">=" + min;
|
applySQLCheck( column, checkConstraint );
|
||||||
applySQLCheck( col, checkConstraint );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,10 +294,9 @@ class TypeSafeActivator {
|
||||||
final long max = maxConstraint.getAnnotation().value();
|
final long max = maxConstraint.getAnnotation().value();
|
||||||
|
|
||||||
for ( Selectable selectable : property.getSelectables() ) {
|
for ( Selectable selectable : property.getSelectables() ) {
|
||||||
if ( selectable instanceof Column ) {
|
if ( selectable instanceof Column column ) {
|
||||||
Column col = (Column) selectable;
|
final String checkConstraint = column.getQuotedName( dialect ) + "<=" + max;
|
||||||
String checkConstraint = col.getQuotedName( dialect ) + "<=" + max;
|
applySQLCheck( column, checkConstraint );
|
||||||
applySQLCheck( col, checkConstraint );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,10 +352,9 @@ class TypeSafeActivator {
|
||||||
int fractionalDigits = digitsConstraint.getAnnotation().fraction();
|
int fractionalDigits = digitsConstraint.getAnnotation().fraction();
|
||||||
|
|
||||||
for ( Selectable selectable : property.getSelectables() ) {
|
for ( Selectable selectable : property.getSelectables() ) {
|
||||||
if ( selectable instanceof Column ) {
|
if ( selectable instanceof Column column ) {
|
||||||
Column col = (Column) selectable;
|
column.setPrecision( integerDigits + fractionalDigits );
|
||||||
col.setPrecision( integerDigits + fractionalDigits );
|
column.setScale( fractionalDigits );
|
||||||
col.setScale( fractionalDigits );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,10 +384,9 @@ class TypeSafeActivator {
|
||||||
int max = (Integer) descriptor.getAttributes().get( "max" );
|
int max = (Integer) descriptor.getAttributes().get( "max" );
|
||||||
|
|
||||||
for ( Selectable selectable : property.getSelectables() ) {
|
for ( Selectable selectable : property.getSelectables() ) {
|
||||||
if ( selectable instanceof Column ) {
|
if ( selectable instanceof Column column ) {
|
||||||
Column col = (Column) selectable;
|
|
||||||
if ( max < Integer.MAX_VALUE ) {
|
if ( max < Integer.MAX_VALUE ) {
|
||||||
col.setLength( max );
|
column.setLength( max );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,44 +10,50 @@ import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import static org.hibernate.internal.util.StringHelper.split;
|
||||||
|
import static org.hibernate.internal.util.collections.CollectionHelper.setOfSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicates the jakarta.validation enum (because javax validation might not be on the runtime classpath)
|
* Duplicates the {@code jakarta.validation} enumeration.
|
||||||
|
* (Because Jakarta Validation might not be on the runtime classpath.)
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public enum ValidationMode {
|
public enum ValidationMode {
|
||||||
AUTO( "auto" ),
|
AUTO,
|
||||||
CALLBACK( "callback" ),
|
CALLBACK,
|
||||||
NONE( "none" ),
|
NONE,
|
||||||
DDL( "ddl" );
|
DDL;
|
||||||
|
|
||||||
private final String externalForm;
|
private String externalForm() {
|
||||||
|
return switch (this) {
|
||||||
ValidationMode(String externalForm) {
|
case AUTO -> "auto";
|
||||||
this.externalForm = externalForm;
|
case CALLBACK -> "callback";
|
||||||
|
case NONE -> "none";
|
||||||
|
case DDL -> "ddl";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<ValidationMode> getModes(Object modeProperty) {
|
public static Set<ValidationMode> getModes(Object modeProperty) {
|
||||||
Set<ValidationMode> modes = CollectionHelper.setOfSize( 3);
|
final Set<ValidationMode> modes = setOfSize( 3);
|
||||||
if (modeProperty == null) {
|
if ( modeProperty == null ) {
|
||||||
modes.add( ValidationMode.AUTO );
|
modes.add( ValidationMode.AUTO );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for ( String modeInString : StringHelper.split( ",", modeProperty.toString() ) ) {
|
for ( String modeInString : split( ",", modeProperty.toString() ) ) {
|
||||||
modes.add( getMode(modeInString) );
|
modes.add( getMode(modeInString) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( modes.size() > 1 && ( modes.contains( ValidationMode.AUTO ) || modes.contains( ValidationMode.NONE ) ) ) {
|
if ( modes.size() > 1
|
||||||
|
&& ( modes.contains( ValidationMode.AUTO ) || modes.contains( ValidationMode.NONE ) ) ) {
|
||||||
throw new HibernateException( "Incompatible validation modes mixed: " + loggable( modes ) );
|
throw new HibernateException( "Incompatible validation modes mixed: " + loggable( modes ) );
|
||||||
}
|
}
|
||||||
return modes;
|
return modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ValidationMode getMode(String modeProperty) {
|
private static ValidationMode getMode(String modeProperty) {
|
||||||
if (modeProperty == null || modeProperty.length() == 0) {
|
if ( modeProperty == null || modeProperty.isEmpty() ) {
|
||||||
return AUTO;
|
return AUTO;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -55,7 +61,9 @@ public enum ValidationMode {
|
||||||
return valueOf( modeProperty.trim().toUpperCase(Locale.ROOT) );
|
return valueOf( modeProperty.trim().toUpperCase(Locale.ROOT) );
|
||||||
}
|
}
|
||||||
catch ( IllegalArgumentException e ) {
|
catch ( IllegalArgumentException e ) {
|
||||||
throw new HibernateException( "Unknown validation mode in " + BeanValidationIntegrator.JAKARTA_MODE_PROPERTY + ": " + modeProperty );
|
throw new HibernateException( "Unknown validation mode in "
|
||||||
|
+ BeanValidationIntegrator.JAKARTA_MODE_PROPERTY
|
||||||
|
+ ": " + modeProperty );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,12 +72,12 @@ public enum ValidationMode {
|
||||||
if ( modes == null || modes.isEmpty() ) {
|
if ( modes == null || modes.isEmpty() ) {
|
||||||
return "[<empty>]";
|
return "[<empty>]";
|
||||||
}
|
}
|
||||||
StringBuilder buffer = new StringBuilder( "[" );
|
final StringBuilder result = new StringBuilder( "[" );
|
||||||
String sep = "";
|
String sep = "";
|
||||||
for ( ValidationMode mode : modes ) {
|
for ( ValidationMode mode : modes ) {
|
||||||
buffer.append( sep ).append( mode.externalForm );
|
result.append( sep ).append( mode.externalForm() );
|
||||||
sep = ", ";
|
sep = ", ";
|
||||||
}
|
}
|
||||||
return buffer.append( "]" ).toString();
|
return result.append( "]" ).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import org.hibernate.boot.spi.SessionFactoryBuilderService;
|
||||||
*/
|
*/
|
||||||
public final class DefaultSessionFactoryBuilderService implements SessionFactoryBuilderService {
|
public final class DefaultSessionFactoryBuilderService implements SessionFactoryBuilderService {
|
||||||
|
|
||||||
protected static final DefaultSessionFactoryBuilderService INSTANCE = new DefaultSessionFactoryBuilderService();
|
static final DefaultSessionFactoryBuilderService INSTANCE = new DefaultSessionFactoryBuilderService();
|
||||||
|
|
||||||
private DefaultSessionFactoryBuilderService() {
|
private DefaultSessionFactoryBuilderService() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -662,45 +662,41 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
final StrategySelector strategySelector = serviceRegistry.requireService( StrategySelector.class );
|
final StrategySelector strategySelector = serviceRegistry.requireService( StrategySelector.class );
|
||||||
final ConfigurationService configService = serviceRegistry.requireService( ConfigurationService.class );
|
final ConfigurationService configService = serviceRegistry.requireService( ConfigurationService.class );
|
||||||
|
|
||||||
this.mappingDefaults = new MappingDefaultsImpl( serviceRegistry );
|
mappingDefaults = new MappingDefaultsImpl( serviceRegistry );
|
||||||
|
|
||||||
this.defaultTimezoneStorage = resolveTimeZoneStorageStrategy( configService );
|
defaultTimezoneStorage = resolveTimeZoneStorageStrategy( configService );
|
||||||
this.wrapperArrayHandling = resolveWrapperArrayHandling( configService, serviceRegistry );
|
wrapperArrayHandling = resolveWrapperArrayHandling( configService, serviceRegistry );
|
||||||
this.multiTenancyEnabled = JdbcEnvironmentImpl.isMultiTenancyEnabled( serviceRegistry );
|
multiTenancyEnabled = JdbcEnvironmentImpl.isMultiTenancyEnabled( serviceRegistry );
|
||||||
|
|
||||||
this.xmlMappingEnabled = configService.getSetting(
|
xmlMappingEnabled = configService.getSetting(
|
||||||
AvailableSettings.XML_MAPPING_ENABLED,
|
AvailableSettings.XML_MAPPING_ENABLED,
|
||||||
BOOLEAN,
|
BOOLEAN,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
this.implicitDiscriminatorsForJoinedInheritanceSupported = configService.getSetting(
|
implicitDiscriminatorsForJoinedInheritanceSupported = configService.getSetting(
|
||||||
AvailableSettings.IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS,
|
AvailableSettings.IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS,
|
||||||
BOOLEAN,
|
BOOLEAN,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
this.explicitDiscriminatorsForJoinedInheritanceSupported = !configService.getSetting(
|
explicitDiscriminatorsForJoinedInheritanceSupported = !configService.getSetting(
|
||||||
AvailableSettings.IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS,
|
AvailableSettings.IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS,
|
||||||
BOOLEAN,
|
BOOLEAN,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
this.implicitlyForceDiscriminatorInSelect = configService.getSetting(
|
implicitlyForceDiscriminatorInSelect = configService.getSetting(
|
||||||
AvailableSettings.FORCE_DISCRIMINATOR_IN_SELECTS_BY_DEFAULT,
|
AvailableSettings.FORCE_DISCRIMINATOR_IN_SELECTS_BY_DEFAULT,
|
||||||
BOOLEAN,
|
BOOLEAN,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
this.sharedCacheMode = configService.getSetting(
|
sharedCacheMode = configService.getSetting(
|
||||||
AvailableSettings.JAKARTA_SHARED_CACHE_MODE,
|
AvailableSettings.JAKARTA_SHARED_CACHE_MODE,
|
||||||
value -> {
|
value -> value instanceof SharedCacheMode cacheMode
|
||||||
if ( value instanceof SharedCacheMode ) {
|
? cacheMode
|
||||||
return (SharedCacheMode) value;
|
: SharedCacheMode.valueOf( value.toString() ),
|
||||||
}
|
|
||||||
|
|
||||||
return SharedCacheMode.valueOf( value.toString() );
|
|
||||||
},
|
|
||||||
configService.getSetting(
|
configService.getSetting(
|
||||||
AvailableSettings.JPA_SHARED_CACHE_MODE,
|
AvailableSettings.JPA_SHARED_CACHE_MODE,
|
||||||
value -> {
|
value -> {
|
||||||
|
@ -713,52 +709,48 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
AvailableSettings.JAKARTA_SHARED_CACHE_MODE
|
AvailableSettings.JAKARTA_SHARED_CACHE_MODE
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( value instanceof SharedCacheMode ) {
|
return value instanceof SharedCacheMode cacheMode
|
||||||
return (SharedCacheMode) value;
|
? cacheMode
|
||||||
}
|
: SharedCacheMode.valueOf( value.toString() );
|
||||||
|
|
||||||
return SharedCacheMode.valueOf( value.toString() );
|
|
||||||
},
|
},
|
||||||
SharedCacheMode.UNSPECIFIED
|
SharedCacheMode.UNSPECIFIED
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.defaultCacheAccessType = configService.getSetting(
|
final RegionFactory regionFactory = serviceRegistry.getService( RegionFactory.class );
|
||||||
|
defaultCacheAccessType = configService.getSetting(
|
||||||
AvailableSettings.DEFAULT_CACHE_CONCURRENCY_STRATEGY,
|
AvailableSettings.DEFAULT_CACHE_CONCURRENCY_STRATEGY,
|
||||||
value -> {
|
value -> {
|
||||||
if ( value == null ) {
|
if ( value == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
else if ( value instanceof CacheConcurrencyStrategy cacheConcurrencyStrategy ) {
|
||||||
if ( value instanceof CacheConcurrencyStrategy ) {
|
return cacheConcurrencyStrategy.toAccessType();
|
||||||
return ( (CacheConcurrencyStrategy) value ).toAccessType();
|
|
||||||
}
|
}
|
||||||
|
else if ( value instanceof AccessType accessType ) {
|
||||||
if ( value instanceof AccessType ) {
|
return accessType;
|
||||||
return (AccessType) value;
|
}
|
||||||
|
else {
|
||||||
|
return AccessType.fromExternalName( value.toString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return AccessType.fromExternalName( value.toString() );
|
|
||||||
},
|
},
|
||||||
// by default, see if the defined RegionFactory (if one) defines a default
|
// by default, see if the defined RegionFactory (if one) defines a default
|
||||||
serviceRegistry.getService( RegionFactory.class ) == null
|
regionFactory == null ? null : regionFactory.getDefaultAccessType()
|
||||||
? null
|
|
||||||
: serviceRegistry.requireService( RegionFactory.class ).getDefaultAccessType()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.specjProprietarySyntaxEnabled = configService.getSetting(
|
specjProprietarySyntaxEnabled = configService.getSetting(
|
||||||
"hibernate.enable_specj_proprietary_syntax",
|
"hibernate.enable_specj_proprietary_syntax",
|
||||||
BOOLEAN,
|
BOOLEAN,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
this.noConstraintByDefault = ConstraintMode.NO_CONSTRAINT.name().equalsIgnoreCase( configService.getSetting(
|
noConstraintByDefault = ConstraintMode.NO_CONSTRAINT.name().equalsIgnoreCase( configService.getSetting(
|
||||||
AvailableSettings.HBM2DDL_DEFAULT_CONSTRAINT_MODE,
|
AvailableSettings.HBM2DDL_DEFAULT_CONSTRAINT_MODE,
|
||||||
String.class,
|
String.class,
|
||||||
null
|
null
|
||||||
) );
|
) );
|
||||||
|
|
||||||
this.implicitNamingStrategy = strategySelector.resolveDefaultableStrategy(
|
implicitNamingStrategy = strategySelector.resolveDefaultableStrategy(
|
||||||
ImplicitNamingStrategy.class,
|
ImplicitNamingStrategy.class,
|
||||||
configService.getSettings().get( AvailableSettings.IMPLICIT_NAMING_STRATEGY ),
|
configService.getSettings().get( AvailableSettings.IMPLICIT_NAMING_STRATEGY ),
|
||||||
new Callable<>() {
|
new Callable<>() {
|
||||||
|
@ -773,13 +765,13 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
this.physicalNamingStrategy = strategySelector.resolveDefaultableStrategy(
|
physicalNamingStrategy = strategySelector.resolveDefaultableStrategy(
|
||||||
PhysicalNamingStrategy.class,
|
PhysicalNamingStrategy.class,
|
||||||
configService.getSettings().get( AvailableSettings.PHYSICAL_NAMING_STRATEGY ),
|
configService.getSettings().get( AvailableSettings.PHYSICAL_NAMING_STRATEGY ),
|
||||||
PhysicalNamingStrategyStandardImpl.INSTANCE
|
PhysicalNamingStrategyStandardImpl.INSTANCE
|
||||||
);
|
);
|
||||||
|
|
||||||
this.columnOrderingStrategy = strategySelector.resolveDefaultableStrategy(
|
columnOrderingStrategy = strategySelector.resolveDefaultableStrategy(
|
||||||
ColumnOrderingStrategy.class,
|
ColumnOrderingStrategy.class,
|
||||||
configService.getSettings().get( AvailableSettings.COLUMN_ORDERING_STRATEGY ),
|
configService.getSettings().get( AvailableSettings.COLUMN_ORDERING_STRATEGY ),
|
||||||
new Callable<>() {
|
new Callable<>() {
|
||||||
|
@ -794,13 +786,13 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
this.useNationalizedCharacterData = configService.getSetting(
|
useNationalizedCharacterData = configService.getSetting(
|
||||||
AvailableSettings.USE_NATIONALIZED_CHARACTER_DATA,
|
AvailableSettings.USE_NATIONALIZED_CHARACTER_DATA,
|
||||||
BOOLEAN,
|
BOOLEAN,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
this.schemaCharset = configService.getSetting(
|
schemaCharset = configService.getSetting(
|
||||||
AvailableSettings.HBM2DDL_CHARSET_NAME,
|
AvailableSettings.HBM2DDL_CHARSET_NAME,
|
||||||
String.class,
|
String.class,
|
||||||
null
|
null
|
||||||
|
@ -841,45 +833,33 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeZoneStorageStrategy toTimeZoneStorageStrategy(TimeZoneSupport timeZoneSupport) {
|
private TimeZoneStorageStrategy toTimeZoneStorageStrategy(TimeZoneSupport timeZoneSupport) {
|
||||||
switch ( defaultTimezoneStorage ) {
|
return switch (defaultTimezoneStorage) {
|
||||||
case NATIVE:
|
case NATIVE -> {
|
||||||
if ( timeZoneSupport != TimeZoneSupport.NATIVE ) {
|
if ( timeZoneSupport != TimeZoneSupport.NATIVE ) {
|
||||||
throw new HibernateException( "The configured time zone storage type NATIVE is not supported with the configured dialect" );
|
throw new HibernateException( "The configured time zone storage type NATIVE is not supported with the configured dialect" );
|
||||||
}
|
}
|
||||||
return TimeZoneStorageStrategy.NATIVE;
|
yield TimeZoneStorageStrategy.NATIVE;
|
||||||
case COLUMN:
|
}
|
||||||
return TimeZoneStorageStrategy.COLUMN;
|
case COLUMN -> TimeZoneStorageStrategy.COLUMN;
|
||||||
case NORMALIZE:
|
case NORMALIZE -> TimeZoneStorageStrategy.NORMALIZE;
|
||||||
return TimeZoneStorageStrategy.NORMALIZE;
|
case NORMALIZE_UTC -> TimeZoneStorageStrategy.NORMALIZE_UTC;
|
||||||
case NORMALIZE_UTC:
|
case AUTO -> switch (timeZoneSupport) {
|
||||||
return TimeZoneStorageStrategy.NORMALIZE_UTC;
|
case NATIVE ->
|
||||||
case AUTO:
|
|
||||||
switch (timeZoneSupport) {
|
|
||||||
case NATIVE:
|
|
||||||
// if the db has native support for timezones, we use that, not a column
|
// if the db has native support for timezones, we use that, not a column
|
||||||
return TimeZoneStorageStrategy.NATIVE;
|
TimeZoneStorageStrategy.NATIVE;
|
||||||
case NORMALIZE:
|
case NORMALIZE, NONE ->
|
||||||
case NONE:
|
|
||||||
// otherwise we use a separate column
|
// otherwise we use a separate column
|
||||||
return TimeZoneStorageStrategy.COLUMN;
|
TimeZoneStorageStrategy.COLUMN;
|
||||||
default:
|
};
|
||||||
throw new HibernateException( "Unsupported time zone support: " + timeZoneSupport);
|
case DEFAULT -> switch (timeZoneSupport) {
|
||||||
}
|
case NATIVE ->
|
||||||
case DEFAULT:
|
|
||||||
switch (timeZoneSupport) {
|
|
||||||
case NATIVE:
|
|
||||||
// if the db has native support for timezones, we use that, and don't normalize
|
// if the db has native support for timezones, we use that, and don't normalize
|
||||||
return TimeZoneStorageStrategy.NATIVE;
|
TimeZoneStorageStrategy.NATIVE;
|
||||||
case NORMALIZE:
|
case NORMALIZE, NONE ->
|
||||||
case NONE:
|
|
||||||
// otherwise we normalize things to UTC
|
// otherwise we normalize things to UTC
|
||||||
return TimeZoneStorageStrategy.NORMALIZE_UTC;
|
TimeZoneStorageStrategy.NORMALIZE_UTC;
|
||||||
default:
|
};
|
||||||
throw new HibernateException( "Unsupported time zone support: " + timeZoneSupport);
|
};
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new HibernateException( "Unsupported time zone storage type: " + defaultTimezoneStorage );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1047,12 +1027,13 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
|| dialect.getPreferredSqlTypeCodeForArray() == SqlTypes.SQLXML ) ) {
|
|| dialect.getPreferredSqlTypeCodeForArray() == SqlTypes.SQLXML ) ) {
|
||||||
return WrapperArrayHandling.ALLOW;
|
return WrapperArrayHandling.ALLOW;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return WrapperArrayHandling.LEGACY;
|
return WrapperArrayHandling.LEGACY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return setting;
|
return setting;
|
||||||
};
|
}
|
||||||
|
|
||||||
private static WrapperArrayHandling resolveFallbackWrapperArrayHandling(
|
private static WrapperArrayHandling resolveFallbackWrapperArrayHandling(
|
||||||
ConfigurationService configService) {
|
ConfigurationService configService) {
|
||||||
|
@ -1060,7 +1041,8 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont
|
||||||
// JPA compliance was enabled. Use PICK
|
// JPA compliance was enabled. Use PICK
|
||||||
return WrapperArrayHandling.PICK;
|
return WrapperArrayHandling.PICK;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return WrapperArrayHandling.DISALLOW;
|
return WrapperArrayHandling.DISALLOW;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,7 +404,7 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override @Deprecated
|
||||||
public SessionFactoryBuilder enableJpaCascadeCompliance(boolean enabled) {
|
public SessionFactoryBuilder enableJpaCascadeCompliance(boolean enabled) {
|
||||||
this.optionsBuilder.enableJpaCascadeCompliance( enabled );
|
this.optionsBuilder.enableJpaCascadeCompliance( enabled );
|
||||||
return this;
|
return this;
|
||||||
|
|
Loading…
Reference in New Issue