miscellaneous code cleanups
This commit is contained in:
parent
57cbf2e16a
commit
47024e7bd5
|
@ -50,20 +50,20 @@ import org.hibernate.internal.util.StringHelper;
|
|||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.ForeignKeyDirection;
|
||||
import org.hibernate.type.OneToOneType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
|
||||
|
||||
/**
|
||||
* Responsible for maintaining the queue of actions related to events.
|
||||
*
|
||||
* The ActionQueue holds the DML operations queued as part of a session's transactional-write-behind semantics. The
|
||||
* DML operations are queued here until a flush forces them to be executed against the database.
|
||||
* <p>
|
||||
* The {@code ActionQueue} holds the DML operations queued as part of a session's transactional-write-behind semantics.
|
||||
* The DML operations are queued here until a flush forces them to be executed against the database.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gail Badner
|
||||
|
@ -76,12 +76,11 @@ public class ActionQueue {
|
|||
|
||||
private UnresolvedEntityInsertActions unresolvedInsertions;
|
||||
|
||||
// NOTE: ExecutableList fields must be instantiated via ListProvider#init or #getOrInit
|
||||
// to ensure that they are instantiated consistently.
|
||||
// NOTE: ExecutableList fields must be instantiated via ListProvider#init
|
||||
// or #getOrInit to ensure that they are instantiated consistently.
|
||||
|
||||
// Object insertions, updates, and deletions have list semantics because
|
||||
// they must happen in the right order so as to respect referential
|
||||
// integrity
|
||||
// they must happen in the right order to respect referential integrity
|
||||
private ExecutableList<AbstractEntityInsertAction> insertions;
|
||||
private ExecutableList<EntityDeleteAction> deletions;
|
||||
private ExecutableList<EntityUpdateAction> updates;
|
||||
|
@ -96,8 +95,8 @@ public class ActionQueue {
|
|||
private ExecutableList<CollectionRemoveAction> collectionRemovals;
|
||||
private ExecutableList<CollectionRemoveAction> orphanCollectionRemovals;
|
||||
|
||||
// TODO: The removeOrphan concept is a temporary "hack" for HHH-6484. This should be removed once action/task
|
||||
// ordering is improved.
|
||||
// TODO: The removeOrphan concept is a temporary "hack" for HHH-6484.
|
||||
// This should be removed once action/task ordering is improved.
|
||||
private ExecutableList<OrphanRemovalAction> orphanRemovals;
|
||||
|
||||
|
||||
|
@ -105,11 +104,11 @@ public class ActionQueue {
|
|||
private AfterTransactionCompletionProcessQueue afterTransactionProcesses;
|
||||
private BeforeTransactionCompletionProcessQueue beforeTransactionProcesses;
|
||||
|
||||
//Extract this as a constant to perform efficient iterations:
|
||||
//method values() otherwise allocates a new array on each invocation.
|
||||
// Extract this as a constant to perform efficient iterations:
|
||||
// method values() otherwise allocates a new array on each invocation.
|
||||
private static final OrderedActions[] ORDERED_OPERATIONS = OrderedActions.values();
|
||||
|
||||
//The order of these operations is very important
|
||||
// The order of these operations is very important
|
||||
private enum OrderedActions {
|
||||
OrphanCollectionRemoveAction {
|
||||
@Override
|
||||
|
@ -266,7 +265,7 @@ public class ActionQueue {
|
|||
LOG.tracev( "Executing inserts before finding non-nullable transient entities for early insert: [{0}]", insert );
|
||||
executeInserts();
|
||||
}
|
||||
NonNullableTransientDependencies nonNullableTransientDependencies = insert.findNonNullableTransientEntities();
|
||||
final NonNullableTransientDependencies nonNullableTransientDependencies = insert.findNonNullableTransientEntities();
|
||||
if ( nonNullableTransientDependencies == null ) {
|
||||
LOG.tracev( "Adding insert with no non-nullable, transient entities: [{0}]", insert );
|
||||
addResolvedEntityInsertAction( insert );
|
||||
|
@ -293,13 +292,13 @@ public class ActionQueue {
|
|||
else {
|
||||
LOG.trace( "Adding resolved non-early insert action." );
|
||||
OrderedActions.EntityInsertAction.ensureInitialized( this );
|
||||
this.insertions.add( insert );
|
||||
insertions.add( insert );
|
||||
}
|
||||
if ( !insert.isVeto() ) {
|
||||
insert.makeEntityManaged();
|
||||
|
||||
if ( unresolvedInsertions != null ) {
|
||||
for ( AbstractEntityInsertAction resolvedAction : unresolvedInsertions.resolveDependentActions( insert.getInstance(), session ) ) {
|
||||
for ( AbstractEntityInsertAction resolvedAction :
|
||||
unresolvedInsertions.resolveDependentActions( insert.getInstance(), session ) ) {
|
||||
addResolvedEntityInsertAction( resolvedAction );
|
||||
}
|
||||
}
|
||||
|
@ -329,7 +328,7 @@ public class ActionQueue {
|
|||
*/
|
||||
public void addAction(EntityDeleteAction action) {
|
||||
OrderedActions.EntityDeleteAction.ensureInitialized( this );
|
||||
this.deletions.add( action );
|
||||
deletions.add( action );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -339,7 +338,7 @@ public class ActionQueue {
|
|||
*/
|
||||
public void addAction(final OrphanRemovalAction action) {
|
||||
OrderedActions.OrphanRemovalAction.ensureInitialized( this );
|
||||
this.orphanRemovals.add( action );
|
||||
orphanRemovals.add( action );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -349,7 +348,7 @@ public class ActionQueue {
|
|||
*/
|
||||
public void addAction(final EntityUpdateAction action) {
|
||||
OrderedActions.EntityUpdateAction.ensureInitialized( this );
|
||||
this.updates.add( action );
|
||||
updates.add( action );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -359,7 +358,7 @@ public class ActionQueue {
|
|||
*/
|
||||
public void addAction(final CollectionRecreateAction action) {
|
||||
OrderedActions.CollectionRecreateAction.ensureInitialized( this );
|
||||
this.collectionCreations.add( action );
|
||||
collectionCreations.add( action );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -368,22 +367,23 @@ public class ActionQueue {
|
|||
* @param action The action representing the removal of a collection
|
||||
*/
|
||||
public void addAction(final CollectionRemoveAction action) {
|
||||
if ( orphanRemovals != null && action.getAffectedOwner() != null && session.getPersistenceContextInternal()
|
||||
.getEntry( action.getAffectedOwner() )
|
||||
.getStatus()
|
||||
.isDeletedOrGone() ) {
|
||||
if ( orphanRemovals != null && action.getAffectedOwner() != null
|
||||
&& session.getPersistenceContextInternal()
|
||||
.getEntry( action.getAffectedOwner() )
|
||||
.getStatus()
|
||||
.isDeletedOrGone() ) {
|
||||
// We need to check if this collection's owner is an orphan being removed,
|
||||
// which case we should remove the collection first to avoid constraint violations
|
||||
for ( OrphanRemovalAction orphanRemoval : orphanRemovals ) {
|
||||
if ( orphanRemoval.getInstance() == action.getAffectedOwner() ) {
|
||||
OrderedActions.OrphanCollectionRemoveAction.ensureInitialized( this );
|
||||
this.orphanCollectionRemovals.add( action );
|
||||
orphanCollectionRemovals.add( action );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
OrderedActions.CollectionRemoveAction.ensureInitialized( this );
|
||||
this.collectionRemovals.add( action );
|
||||
collectionRemovals.add( action );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -393,7 +393,7 @@ public class ActionQueue {
|
|||
*/
|
||||
public void addAction(final CollectionUpdateAction action) {
|
||||
OrderedActions.CollectionUpdateAction.ensureInitialized( this );
|
||||
this.collectionUpdates.add( action );
|
||||
collectionUpdates.add( action );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,7 +423,7 @@ public class ActionQueue {
|
|||
beforeTransactionProcesses.register( executable.getBeforeTransactionCompletionProcess() );
|
||||
}
|
||||
if ( session.getFactory().getSessionFactoryOptions().isQueryCacheEnabled() ) {
|
||||
invalidateSpaces( convertTimestampSpaces( executable.getPropertySpaces() ) );
|
||||
invalidateSpaces( (String[]) executable.getPropertySpaces() );
|
||||
}
|
||||
if ( executable.getAfterTransactionCompletionProcess() != null ) {
|
||||
if ( afterTransactionProcesses == null ) {
|
||||
|
@ -433,10 +433,6 @@ public class ActionQueue {
|
|||
}
|
||||
}
|
||||
|
||||
private static String[] convertTimestampSpaces(Serializable[] spaces) {
|
||||
return (String[]) spaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are there unresolved entity insert actions that depend on non-nullable associations with a transient entity?
|
||||
*
|
||||
|
@ -653,8 +649,7 @@ public class ActionQueue {
|
|||
// Strictly speaking, only a subset of the list may have been processed if a RuntimeException occurs.
|
||||
// We still invalidate all spaces. I don't see this as a big deal - after all, RuntimeExceptions are
|
||||
// unexpected.
|
||||
Set propertySpaces = list.getQuerySpaces();
|
||||
invalidateSpaces( convertTimestampSpaces( propertySpaces ) );
|
||||
invalidateSpaces( list.getQuerySpaces().toArray(StringHelper.EMPTY_STRINGS) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,10 +657,6 @@ public class ActionQueue {
|
|||
session.getJdbcCoordinator().executeBatch();
|
||||
}
|
||||
|
||||
private static String[] convertTimestampSpaces(Set<String> spaces) {
|
||||
return spaces.toArray(StringHelper.EMPTY_STRINGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param executable The action to execute
|
||||
*/
|
||||
|
@ -683,7 +674,7 @@ public class ActionQueue {
|
|||
*
|
||||
* @param spaces The spaces to invalidate
|
||||
*/
|
||||
private void invalidateSpaces(String... spaces) {
|
||||
private void invalidateSpaces(String[] spaces) {
|
||||
if ( spaces != null && spaces.length > 0 ) {
|
||||
for ( String space : spaces ) {
|
||||
if ( afterTransactionProcesses == null ) {
|
||||
|
@ -855,10 +846,18 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
public boolean hasAnyQueuedActions() {
|
||||
return ( updates != null && !updates.isEmpty() ) || ( insertions != null && !insertions.isEmpty() ) || hasUnresolvedEntityInsertActions()
|
||||
|| ( deletions != null && !deletions.isEmpty()) || ( collectionUpdates != null && !collectionUpdates.isEmpty() )
|
||||
|| ( collectionQueuedOps != null && !collectionQueuedOps.isEmpty() ) || ( collectionRemovals != null && !collectionRemovals.isEmpty() )
|
||||
|| ( collectionCreations != null && !collectionCreations.isEmpty() );
|
||||
return hasUnresolvedEntityInsertActions()
|
||||
|| nonempty( updates )
|
||||
|| nonempty( insertions )
|
||||
|| nonempty( deletions )
|
||||
|| nonempty( collectionUpdates )
|
||||
|| nonempty( collectionQueuedOps )
|
||||
|| nonempty( collectionRemovals )
|
||||
|| nonempty( collectionCreations );
|
||||
}
|
||||
|
||||
private boolean nonempty(ExecutableList<?> list) {
|
||||
return list != null && !list.isEmpty();
|
||||
}
|
||||
|
||||
public void unScheduleUnloadedDeletion(Object newEntity) {
|
||||
|
@ -866,13 +865,12 @@ public class ActionQueue {
|
|||
final Object identifier = entityPersister.getIdentifier( newEntity, session );
|
||||
if ( deletions != null ) {
|
||||
for ( int i = 0; i < deletions.size(); i++ ) {
|
||||
EntityDeleteAction action = deletions.get( i );
|
||||
final EntityDeleteAction action = deletions.get( i );
|
||||
if ( action.getInstance() == null
|
||||
&& action.getEntityName().equals( entityPersister.getEntityName() )
|
||||
&& entityPersister.getIdentifierMapping().areEqual( action.getId(), identifier, session ) ) {
|
||||
session.getPersistenceContextInternal().removeDeletedUnloadedEntityKey(
|
||||
session.generateEntityKey( identifier, entityPersister )
|
||||
);
|
||||
session.getPersistenceContextInternal()
|
||||
.removeDeletedUnloadedEntityKey( session.generateEntityKey( identifier, entityPersister ) );
|
||||
deletions.remove( i );
|
||||
return;
|
||||
}
|
||||
|
@ -882,7 +880,7 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
public void unScheduleDeletion(EntityEntry entry, Object rescuedEntity) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( rescuedEntity );
|
||||
final LazyInitializer lazyInitializer = extractLazyInitializer( rescuedEntity );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( !lazyInitializer.isUninitialized() ) {
|
||||
rescuedEntity = lazyInitializer.getImplementation( session );
|
||||
|
@ -890,7 +888,7 @@ public class ActionQueue {
|
|||
}
|
||||
if ( deletions != null ) {
|
||||
for ( int i = 0; i < deletions.size(); i++ ) {
|
||||
EntityDeleteAction action = deletions.get( i );
|
||||
final EntityDeleteAction action = deletions.get( i );
|
||||
if ( action.getInstance() == rescuedEntity ) {
|
||||
deletions.remove( i );
|
||||
return;
|
||||
|
@ -899,7 +897,7 @@ public class ActionQueue {
|
|||
}
|
||||
if ( orphanRemovals != null ) {
|
||||
for ( int i = 0; i < orphanRemovals.size(); i++ ) {
|
||||
EntityDeleteAction action = orphanRemovals.get( i );
|
||||
final EntityDeleteAction action = orphanRemovals.get( i );
|
||||
if ( action.getInstance() == rescuedEntity ) {
|
||||
orphanRemovals.remove( i );
|
||||
return;
|
||||
|
@ -923,7 +921,7 @@ public class ActionQueue {
|
|||
unresolvedInsertions.serialize( oos );
|
||||
|
||||
for ( OrderedActions action : ORDERED_OPERATIONS ) {
|
||||
ExecutableList<?> l = action.getActions( this );
|
||||
final ExecutableList<?> l = action.getActions( this );
|
||||
if ( l == null ) {
|
||||
oos.writeBoolean( false );
|
||||
}
|
||||
|
@ -985,10 +983,9 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
public void register(T process) {
|
||||
if ( process == null ) {
|
||||
return;
|
||||
if ( process != null ) {
|
||||
processes.add( process );
|
||||
}
|
||||
processes.add( process );
|
||||
}
|
||||
|
||||
public boolean hasActions() {
|
||||
|
@ -999,7 +996,9 @@ public class ActionQueue {
|
|||
/**
|
||||
* Encapsulates behavior needed for before transaction processing
|
||||
*/
|
||||
private static class BeforeTransactionCompletionProcessQueue extends AbstractTransactionCompletionProcessQueue<BeforeTransactionCompletionProcess> {
|
||||
private static class BeforeTransactionCompletionProcessQueue
|
||||
extends AbstractTransactionCompletionProcessQueue<BeforeTransactionCompletionProcess> {
|
||||
|
||||
private BeforeTransactionCompletionProcessQueue(SessionImplementor session) {
|
||||
super( session );
|
||||
}
|
||||
|
@ -1111,26 +1110,26 @@ public class ActionQueue {
|
|||
public void buildDirectDependencies(IdentityHashMap<Object, InsertInfo> insertInfosByEntity) {
|
||||
final Object[] propertyValues = insertAction.getState();
|
||||
final Type[] propertyTypes = insertAction.getPersister().getPropertyTypes();
|
||||
for (int i = 0, propertyTypesLength = propertyTypes.length; i < propertyTypesLength; i++) {
|
||||
addDirectDependency(propertyTypes[i], propertyValues[i], insertInfosByEntity);
|
||||
for ( int i = 0, propertyTypesLength = propertyTypes.length; i < propertyTypesLength; i++ ) {
|
||||
addDirectDependency( propertyTypes[i], propertyValues[i], insertInfosByEntity );
|
||||
}
|
||||
}
|
||||
|
||||
public void propagateChildDependencies() {
|
||||
if ( outgoingDependencies != null ) {
|
||||
for (InsertInfo childDependency : outgoingDependencies) {
|
||||
for ( InsertInfo childDependency : outgoingDependencies ) {
|
||||
if (childDependency.transitiveIncomingDependencies == null) {
|
||||
childDependency.transitiveIncomingDependencies = new HashSet<>();
|
||||
}
|
||||
childDependency.transitiveIncomingDependencies.add(this);
|
||||
childDependency.transitiveIncomingDependencies.add( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void buildTransitiveDependencies(Set<InsertInfo> visited) {
|
||||
if (transitiveIncomingDependencies != null) {
|
||||
visited.addAll(transitiveIncomingDependencies);
|
||||
for (InsertInfo insertInfo : transitiveIncomingDependencies.toArray(new InsertInfo[0])) {
|
||||
if ( transitiveIncomingDependencies != null ) {
|
||||
visited.addAll( transitiveIncomingDependencies );
|
||||
for ( InsertInfo insertInfo : transitiveIncomingDependencies.toArray(new InsertInfo[0]) ) {
|
||||
insertInfo.addTransitiveDependencies(this, visited);
|
||||
}
|
||||
visited.clear();
|
||||
|
@ -1138,11 +1137,11 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
public void addTransitiveDependencies(InsertInfo origin, Set<InsertInfo> visited) {
|
||||
if (transitiveIncomingDependencies != null) {
|
||||
for (InsertInfo insertInfo : transitiveIncomingDependencies) {
|
||||
if (visited.add(insertInfo)) {
|
||||
origin.transitiveIncomingDependencies.add(insertInfo);
|
||||
insertInfo.addTransitiveDependencies(origin, visited);
|
||||
if ( transitiveIncomingDependencies != null ) {
|
||||
for ( InsertInfo insertInfo : transitiveIncomingDependencies ) {
|
||||
if ( visited.add(insertInfo) ) {
|
||||
origin.transitiveIncomingDependencies.add( insertInfo );
|
||||
insertInfo.addTransitiveDependencies( origin, visited );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1151,21 +1150,22 @@ public class ActionQueue {
|
|||
private void addDirectDependency(Type type, Object value, IdentityHashMap<Object, InsertInfo> insertInfosByEntity) {
|
||||
if ( type.isEntityType() && value != null ) {
|
||||
final EntityType entityType = (EntityType) type;
|
||||
final InsertInfo insertInfo = insertInfosByEntity.get(value);
|
||||
if (insertInfo != null) {
|
||||
if (entityType.isOneToOne() && OneToOneType.class.cast( entityType).getForeignKeyDirection() == ForeignKeyDirection.TO_PARENT) {
|
||||
if (!entityType.isReferenceToPrimaryKey()) {
|
||||
if (outgoingDependencies == null) {
|
||||
final InsertInfo insertInfo = insertInfosByEntity.get( value );
|
||||
if ( insertInfo != null ) {
|
||||
if ( entityType.isOneToOne()
|
||||
&& entityType.getForeignKeyDirection() == ForeignKeyDirection.TO_PARENT ) {
|
||||
if ( !entityType.isReferenceToPrimaryKey() ) {
|
||||
if ( outgoingDependencies == null ) {
|
||||
outgoingDependencies = new HashSet<>();
|
||||
}
|
||||
outgoingDependencies.add(insertInfo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (transitiveIncomingDependencies == null) {
|
||||
if ( transitiveIncomingDependencies == null ) {
|
||||
transitiveIncomingDependencies = new HashSet<>();
|
||||
}
|
||||
transitiveIncomingDependencies.add(insertInfo);
|
||||
transitiveIncomingDependencies.add( insertInfo );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1176,7 +1176,8 @@ public class ActionQueue {
|
|||
.getMappingMetamodel()
|
||||
.getCollectionDescriptor( collectionType.getRole() )
|
||||
.getAttributeMapping();
|
||||
// We only care about mappedBy one-to-many associations, because for these, the elements depend on the collection owner
|
||||
// We only care about mappedBy one-to-many associations, because for these,
|
||||
// the elements depend on the collection owner
|
||||
if ( pluralAttributeMapping.getCollectionDescriptor().isOneToMany()
|
||||
&& pluralAttributeMapping.getElementDescriptor() instanceof EntityCollectionPart ) {
|
||||
final Iterator<?> elementsIterator = collectionType.getElementsIterator( value );
|
||||
|
@ -1194,29 +1195,28 @@ public class ActionQueue {
|
|||
}
|
||||
else if ( type.isComponentType() && value != null ) {
|
||||
// Support recursive checks of composite type properties for associations and collections.
|
||||
CompositeType compositeType = (CompositeType) type;
|
||||
final CompositeType compositeType = (CompositeType) type;
|
||||
final SharedSessionContractImplementor session = insertAction.getSession();
|
||||
Object[] componentValues = compositeType.getPropertyValues( value, session );
|
||||
final Object[] componentValues = compositeType.getPropertyValues( value, session );
|
||||
for ( int j = 0; j < componentValues.length; ++j ) {
|
||||
Type componentValueType = compositeType.getSubtypes()[j];
|
||||
Object componentValue = componentValues[j];
|
||||
addDirectDependency( componentValueType, componentValue, insertInfosByEntity);
|
||||
final Type componentValueType = compositeType.getSubtypes()[j];
|
||||
final Object componentValue = componentValues[j];
|
||||
addDirectDependency( componentValueType, componentValue, insertInfosByEntity );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InsertInfo that = (InsertInfo) o;
|
||||
|
||||
return insertAction.equals(that.insertAction);
|
||||
final InsertInfo that = (InsertInfo) o;
|
||||
return insertAction.equals( that.insertAction );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1272,20 +1272,13 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
@Override
|
||||
public <T> JpaCriteriaParameter<T> parameter(Class<T> paramClass, String name) {
|
||||
final BasicType<T> basicType = getTypeConfiguration().getBasicTypeForJavaType( paramClass );
|
||||
if ( basicType == null ) {
|
||||
final BindableType<T> parameterType;
|
||||
if ( Collection.class.isAssignableFrom( paramClass ) ) {
|
||||
// a Collection-valued, multi-valued parameter
|
||||
parameterType = new MultiValueParameterType<>( (Class<T>) Collection.class );
|
||||
}
|
||||
else {
|
||||
parameterType = null;
|
||||
}
|
||||
return new JpaCriteriaParameter<>( name, parameterType, true, this );
|
||||
}
|
||||
else {
|
||||
return new JpaCriteriaParameter<>( name, basicType, false, this );
|
||||
}
|
||||
boolean notBasic = basicType == null;
|
||||
final BindableType<T> parameterType =
|
||||
notBasic && Collection.class.isAssignableFrom( paramClass )
|
||||
// a Collection-valued, multi-valued parameter
|
||||
? new MultiValueParameterType<>( (Class<T>) Collection.class )
|
||||
: basicType;
|
||||
return new JpaCriteriaParameter<>( name, parameterType, notBasic, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,12 +16,16 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
||||
/**
|
||||
* Abstract superclass of the built in Type hierarchy.
|
||||
* Abstract superclass of the built-in {@link Type} hierarchy.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public abstract class AbstractType implements Type {
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
protected static final Size LEGACY_DICTATED_SIZE = new Size();
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
protected static final Size LEGACY_DEFAULT_SIZE = new Size( 19, 2, 255L, Size.LobMultiplier.NONE ); // to match legacy behavior
|
||||
|
||||
@Override
|
||||
|
@ -44,46 +48,32 @@ public abstract class AbstractType implements Type {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public int compare(Object x, Object y) {
|
||||
return ( (Comparable) x ).compareTo(y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
|
||||
if (value==null) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return (Serializable) deepCopy( value, session.getFactory() );
|
||||
}
|
||||
throws HibernateException {
|
||||
return value == null ? null : (Serializable) deepCopy( value, session.getFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory) throws HibernateException {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return (Serializable) deepCopy( value, sessionFactory );
|
||||
}
|
||||
public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory)
|
||||
throws HibernateException {
|
||||
return value == null ? null : (Serializable) deepCopy( value, sessionFactory );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(Serializable cached, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
if ( cached==null ) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return deepCopy( cached, session.getFactory() );
|
||||
}
|
||||
return cached == null ? null : deepCopy( cached, session.getFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirty(Object old, Object current, SharedSessionContractImplementor session) throws HibernateException {
|
||||
public boolean isDirty(Object old, Object current, SharedSessionContractImplementor session)
|
||||
throws HibernateException {
|
||||
return !isSame( old, current );
|
||||
}
|
||||
|
||||
|
@ -94,8 +84,8 @@ public abstract class AbstractType implements Type {
|
|||
|
||||
@Override
|
||||
public boolean isModified(Object old, Object current, boolean[] checkable, SharedSessionContractImplementor session)
|
||||
throws HibernateException {
|
||||
return isDirty(old, current, session);
|
||||
throws HibernateException {
|
||||
return isDirty( old, current, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -115,12 +105,12 @@ public abstract class AbstractType implements Type {
|
|||
|
||||
@Override
|
||||
public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory) {
|
||||
return isEqual(x, y );
|
||||
return isEqual( x, y );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHashCode(Object x, SessionFactoryImplementor factory) {
|
||||
return getHashCode(x );
|
||||
return getHashCode( x );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -132,24 +122,19 @@ public abstract class AbstractType implements Type {
|
|||
Map<Object, Object> copyCache,
|
||||
ForeignKeyDirection foreignKeyDirection)
|
||||
throws HibernateException {
|
||||
boolean include;
|
||||
return needsReplacement( foreignKeyDirection ) ? replace( original, target, session, owner, copyCache ) : target;
|
||||
}
|
||||
|
||||
private boolean needsReplacement(ForeignKeyDirection foreignKeyDirection) {
|
||||
if ( isAssociationType() ) {
|
||||
AssociationType atype = (AssociationType) this;
|
||||
include = atype.getForeignKeyDirection()==foreignKeyDirection;
|
||||
final AssociationType associationType = (AssociationType) this;
|
||||
return associationType.getForeignKeyDirection() == foreignKeyDirection;
|
||||
}
|
||||
else {
|
||||
include = ForeignKeyDirection.FROM_PARENT ==foreignKeyDirection;
|
||||
return ForeignKeyDirection.FROM_PARENT == foreignKeyDirection;
|
||||
}
|
||||
return include ? replace(original, target, session, owner, copyCache) : target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeAssemble(Serializable cached, SharedSessionContractImplementor session) {}
|
||||
|
||||
/*public Object copy(Object original, Object target, SharedSessionContractImplementor session, Object owner, Map copyCache)
|
||||
throws HibernateException {
|
||||
if (original==null) return null;
|
||||
return assemble( disassemble(original, session), session, owner );
|
||||
}*/
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.MappingException;
|
||||
import org.hibernate.PropertyNotFoundException;
|
||||
import org.hibernate.Remove;
|
||||
import org.hibernate.boot.spi.BootstrapContext;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
|
@ -26,11 +27,11 @@ import org.hibernate.engine.spi.Mapping;
|
|||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.generator.Generator;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
||||
|
@ -39,12 +40,15 @@ import org.hibernate.property.access.spi.PropertyAccess;
|
|||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.spi.CompositeTypeImplementor;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
|
||||
import static org.hibernate.internal.util.ReflectHelper.isRecord;
|
||||
|
||||
/**
|
||||
* Handles "component" mappings
|
||||
* Handles {@linkplain jakarta.persistence.Embedded embedded} mappings.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
|
@ -63,15 +67,14 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
private final boolean isAggregate;
|
||||
private final boolean isKey;
|
||||
private boolean hasNotNullProperty;
|
||||
private final CompositeUserType<Object> compositeUserType;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final CompositeUserType compositeUserType;
|
||||
|
||||
private EmbeddableValuedModelPart mappingModelPart;
|
||||
|
||||
public ComponentType(Component component, int[] originalPropertyOrder, MetadataBuildingContext buildingContext) {
|
||||
this.componentClass = component.isDynamic()
|
||||
? Map.class
|
||||
: component.getComponentClass();
|
||||
|
||||
this.componentClass = component.isDynamic() ? Map.class : component.getComponentClass();
|
||||
this.isAggregate = component.getAggregateColumn() != null;
|
||||
this.isKey = component.isKey();
|
||||
this.propertySpan = component.getPropertySpan();
|
||||
|
@ -95,26 +98,22 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
i++;
|
||||
}
|
||||
|
||||
if ( component.getTypeName() != null ) {
|
||||
final ManagedBeanRegistry beanRegistry = buildingContext.getBootstrapContext()
|
||||
.getServiceRegistry()
|
||||
.getService( ManagedBeanRegistry.class );
|
||||
final Class<CompositeUserType<?>> customTypeClass = buildingContext.getBootstrapContext()
|
||||
.getClassLoaderAccess()
|
||||
.classForName( component.getTypeName() );
|
||||
if ( buildingContext.getBuildingOptions().disallowExtensionsInCdi() ) {
|
||||
//noinspection unchecked,rawtypes
|
||||
this.compositeUserType = (CompositeUserType) FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( customTypeClass );
|
||||
}
|
||||
else {
|
||||
//noinspection unchecked,rawtypes
|
||||
this.compositeUserType = (CompositeUserType) beanRegistry.getBean( customTypeClass ).getBeanInstance();
|
||||
}
|
||||
this.compositeUserType =
|
||||
component.getTypeName() == null ? null : createCompositeUserType( component, buildingContext );
|
||||
this.mutable = !isRecord( componentClass ) && ( compositeUserType == null || compositeUserType.isMutable() );
|
||||
}
|
||||
|
||||
private static CompositeUserType<?> createCompositeUserType(Component component, MetadataBuildingContext buildingContext) {
|
||||
final BootstrapContext bootstrapContext = buildingContext.getBootstrapContext();
|
||||
final Class<CompositeUserType<?>> customTypeClass =
|
||||
bootstrapContext.getClassLoaderAccess().classForName( component.getTypeName() );
|
||||
if ( buildingContext.getBuildingOptions().disallowExtensionsInCdi() ) {
|
||||
return FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( customTypeClass );
|
||||
}
|
||||
else {
|
||||
this.compositeUserType = null;
|
||||
return bootstrapContext.getServiceRegistry().requireService( ManagedBeanRegistry.class )
|
||||
.getBean( customTypeClass ).getBeanInstance();
|
||||
}
|
||||
this.mutable = !ReflectHelper.isRecord( componentClass ) && ( compositeUserType == null || compositeUserType.isMutable() );
|
||||
}
|
||||
|
||||
private boolean isAggregate() {
|
||||
|
@ -137,7 +136,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
@Override
|
||||
public int[] getSqlTypeCodes(Mapping mapping) throws MappingException {
|
||||
//Not called at runtime so doesn't matter if it's slow :)
|
||||
int[] sqlTypes = new int[getColumnSpan( mapping )];
|
||||
final int[] sqlTypes = new int[getColumnSpan( mapping )];
|
||||
int n = 0;
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
int[] subtypes = propertyTypes[i].getSqlTypeCodes( mapping );
|
||||
|
@ -164,8 +163,8 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
return true;
|
||||
}
|
||||
// null value and empty component are considered equivalent
|
||||
Object[] xvalues = getPropertyValues( x );
|
||||
Object[] yvalues = getPropertyValues( y );
|
||||
final Object[] xvalues = getPropertyValues( x );
|
||||
final Object[] yvalues = getPropertyValues( y );
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
if ( !propertyTypes[i].isSame( xvalues[i], yvalues[i] ) ) {
|
||||
return false;
|
||||
|
@ -248,7 +247,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
int result = 17;
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
Object y = getPropertyValue( x, i );
|
||||
final Object y = getPropertyValue( x, i );
|
||||
result *= 37;
|
||||
if ( y != null ) {
|
||||
result += propertyTypes[i].getHashCode( y );
|
||||
|
@ -264,7 +263,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
int result = 17;
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
Object y = getPropertyValue( x, i );
|
||||
final Object y = getPropertyValue( x, i );
|
||||
result *= 37;
|
||||
if ( y != null ) {
|
||||
result += propertyTypes[i].getHashCode( y, factory );
|
||||
|
@ -304,7 +303,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
}
|
||||
else {
|
||||
boolean[] subcheckable = new boolean[len];
|
||||
final boolean[] subcheckable = new boolean[len];
|
||||
System.arraycopy( checkable, loc, subcheckable, 0, len );
|
||||
final boolean dirty = propertyTypes[i].isDirty(
|
||||
getPropertyValue( x, i ),
|
||||
|
@ -333,8 +332,8 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
// null value and empty components are considered equivalent
|
||||
int loc = 0;
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
int len = propertyTypes[i].getColumnSpan( session.getFactory() );
|
||||
boolean[] subcheckable = new boolean[len];
|
||||
final int len = propertyTypes[i].getColumnSpan( session.getFactory() );
|
||||
final boolean[] subcheckable = new boolean[len];
|
||||
System.arraycopy( checkable, loc, subcheckable, 0, len );
|
||||
if ( propertyTypes[i].isModified( getPropertyValue( old, i ), getPropertyValue( current, i ), subcheckable, session ) ) {
|
||||
return true;
|
||||
|
@ -366,7 +365,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
SharedSessionContractImplementor session)
|
||||
throws HibernateException, SQLException {
|
||||
|
||||
Object[] subvalues = nullSafeGetValues( value );
|
||||
final Object[] subvalues = nullSafeGetValues( value );
|
||||
int loc = 0;
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
int len = propertyTypes[i].getColumnSpan( session.getFactory() );
|
||||
|
@ -381,7 +380,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
}
|
||||
else {
|
||||
boolean[] subsettable = new boolean[len];
|
||||
final boolean[] subsettable = new boolean[len];
|
||||
System.arraycopy( settable, loc, subsettable, 0, len );
|
||||
propertyTypes[i].nullSafeSet( st, subvalues[i], begin, subsettable, session );
|
||||
begin += ArrayHelper.countTrue( subsettable );
|
||||
|
@ -409,18 +408,15 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
if ( component == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( component instanceof Object[] ) {
|
||||
else if ( component instanceof Object[] ) {
|
||||
// A few calls to hashCode pass the property values already in an
|
||||
// Object[] (ex: QueryKey hash codes for cached queries).
|
||||
// It's easiest to just check for the condition here prior to
|
||||
// trying reflection.
|
||||
return ( (Object[]) component )[i];
|
||||
return ((Object[]) component)[i];
|
||||
}
|
||||
else {
|
||||
return mappingModelPart
|
||||
.getEmbeddableTypeDescriptor()
|
||||
.getValue( component, i );
|
||||
return embeddableTypeDescriptor().getValue( component, i );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,15 +438,13 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
return (Object[]) component;
|
||||
}
|
||||
else {
|
||||
return mappingModelPart
|
||||
.getEmbeddableTypeDescriptor()
|
||||
.getValues( component );
|
||||
return embeddableTypeDescriptor().getValues( component );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyValues(Object component, Object[] values) {
|
||||
mappingModelPart.getEmbeddableTypeDescriptor().setValues( component, values );
|
||||
embeddableTypeDescriptor().setValues( component, values );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -475,8 +469,8 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
return "null";
|
||||
}
|
||||
|
||||
Map<String, String> result = new HashMap<>();
|
||||
Object[] values = getPropertyValues( value );
|
||||
final Map<String, String> result = new HashMap<>();
|
||||
final Object[] values = getPropertyValues( value );
|
||||
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||
if ( values[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
|
||||
result.put( propertyNames[i], "<uninitialized>" );
|
||||
|
@ -507,10 +501,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
values[i] = propertyTypes[i].deepCopy( values[i], factory );
|
||||
}
|
||||
|
||||
final EmbeddableInstantiator instantiator = mappingModelPart.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
.getInstantiator();
|
||||
Object result = instantiator.instantiate( () -> values, factory );
|
||||
final Object result = instantiator().instantiate( () -> values, factory );
|
||||
|
||||
//not absolutely necessary, but helps for some
|
||||
//equals()/hashCode() implementations
|
||||
|
@ -561,10 +552,8 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
);
|
||||
|
||||
if ( target == null ) {
|
||||
final EmbeddableInstantiator instantiator = mappingModelPart.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
.getInstantiator();
|
||||
return instantiator.instantiate( () -> replacedValues, session.getSessionFactory() );
|
||||
return instantiator()
|
||||
.instantiate( () -> replacedValues, session.getSessionFactory() );
|
||||
}
|
||||
else {
|
||||
setPropertyValues( target, replacedValues );
|
||||
|
@ -592,7 +581,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
//if ( original == target ) return target;
|
||||
|
||||
|
||||
final Object[] originalValues = getPropertyValues( original );
|
||||
final Object[] resultValues;
|
||||
|
||||
|
@ -614,10 +602,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
);
|
||||
|
||||
if ( target == null ) {
|
||||
final EmbeddableInstantiator instantiator = mappingModelPart.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
.getInstantiator();
|
||||
return instantiator.instantiate( () -> replacedValues, session.getSessionFactory() );
|
||||
return instantiator().instantiate( () -> replacedValues, session.getSessionFactory() );
|
||||
}
|
||||
else {
|
||||
setPropertyValues( target, replacedValues );
|
||||
|
@ -638,7 +623,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
@Override
|
||||
public Serializable disassemble(Object value, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -646,7 +630,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
return compositeUserType.disassemble( value );
|
||||
}
|
||||
else {
|
||||
Object[] values = getPropertyValues( value );
|
||||
final Object[] values = getPropertyValues( value );
|
||||
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||
values[i] = propertyTypes[i].disassemble( values[i], session, owner );
|
||||
}
|
||||
|
@ -663,7 +647,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
return compositeUserType.disassemble( value );
|
||||
}
|
||||
else {
|
||||
Object[] values = getPropertyValues( value );
|
||||
final Object[] values = getPropertyValues( value );
|
||||
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||
values[i] = propertyTypes[i].disassemble( values[i], sessionFactory );
|
||||
}
|
||||
|
@ -682,16 +666,13 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
return compositeUserType.assemble( object, owner );
|
||||
}
|
||||
else {
|
||||
Object[] values = (Object[]) object;
|
||||
Object[] assembled = new Object[values.length];
|
||||
final Object[] values = (Object[]) object;
|
||||
final Object[] assembled = new Object[values.length];
|
||||
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||
assembled[i] = propertyTypes[i].assemble( (Serializable) values[i], session, owner );
|
||||
}
|
||||
|
||||
final EmbeddableInstantiator instantiator = mappingModelPart.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
.getInstantiator();
|
||||
return instantiator.instantiate( () -> assembled, session.getFactory() );
|
||||
return instantiator().instantiate( () -> assembled, session.getFactory() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -707,16 +688,15 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
|
||||
@Override
|
||||
public boolean[] toColumnNullness(Object value, Mapping mapping) {
|
||||
boolean[] result = new boolean[getColumnSpan( mapping )];
|
||||
if ( value == null ) {
|
||||
return result;
|
||||
}
|
||||
Object[] values = getPropertyValues( value ); //TODO!!!!!!!
|
||||
int loc = 0;
|
||||
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||
boolean[] propertyNullness = propertyTypes[i].toColumnNullness( values[i], mapping );
|
||||
System.arraycopy( propertyNullness, 0, result, loc, propertyNullness.length );
|
||||
loc += propertyNullness.length;
|
||||
final boolean[] result = new boolean[getColumnSpan( mapping )];
|
||||
if ( value != null ) {
|
||||
final Object[] values = getPropertyValues( value ); //TODO!!!!!!!
|
||||
int loc = 0;
|
||||
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||
final boolean[] propertyNullness = propertyTypes[i].toColumnNullness( values[i], mapping );
|
||||
System.arraycopy( propertyNullness, 0, result, loc, propertyNullness.length );
|
||||
loc += propertyNullness.length;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -728,7 +708,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
|
||||
@Override
|
||||
public int getPropertyIndex(String name) {
|
||||
String[] names = getPropertyNames();
|
||||
final String[] names = getPropertyNames();
|
||||
for ( int i = 0, max = names.length; i < max; i++ ) {
|
||||
if ( names[i].equals( name ) ) {
|
||||
return i;
|
||||
|
@ -756,7 +736,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
|
||||
@Override
|
||||
public JdbcType getJdbcType() {
|
||||
final SelectableMapping aggregateMapping = mappingModelPart.getEmbeddableTypeDescriptor().getAggregateMapping();
|
||||
final SelectableMapping aggregateMapping = embeddableTypeDescriptor().getAggregateMapping();
|
||||
return aggregateMapping == null ? null : aggregateMapping.getJdbcMapping().getJdbcType();
|
||||
}
|
||||
|
||||
|
@ -776,10 +756,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
public Object extract(CallableStatement statement, int startIndex, SharedSessionContractImplementor session) throws SQLException {
|
||||
Object[] values;
|
||||
if ( isAggregate() ) {
|
||||
values = (Object[]) getMappingModelPart().getEmbeddableTypeDescriptor().getAggregateMapping()
|
||||
.getJdbcMapping()
|
||||
.getJdbcValueExtractor()
|
||||
.extract( statement, startIndex, session );
|
||||
values = (Object[]) jdbcValueExtractor().extract( statement, startIndex, session );
|
||||
}
|
||||
else {
|
||||
values = new Object[propertySpan];
|
||||
|
@ -788,8 +765,9 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
// we know this cast is safe from canDoExtraction
|
||||
final Type propertyType = propertyTypes[i];
|
||||
final Object value = ( (ProcedureParameterExtractionAware<?>) propertyType )
|
||||
.extract( statement, currentIndex, session );
|
||||
final ProcedureParameterExtractionAware<?> extractionAware =
|
||||
(ProcedureParameterExtractionAware<?>) propertyType;
|
||||
final Object value = extractionAware.extract( statement, currentIndex, session );
|
||||
if ( value == null ) {
|
||||
if ( isKey ) {
|
||||
return null; //different nullability rules for pk/fk
|
||||
|
@ -813,21 +791,24 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
@Override
|
||||
public Object extract(CallableStatement statement, String paramName, SharedSessionContractImplementor session)
|
||||
throws SQLException {
|
||||
|
||||
assert isAggregate();
|
||||
final Object[] values = (Object[]) getMappingModelPart().getEmbeddableTypeDescriptor().getAggregateMapping()
|
||||
.getJdbcMapping()
|
||||
.getJdbcValueExtractor()
|
||||
.extract( statement, paramName, session );
|
||||
|
||||
return resolve( values, session );
|
||||
return resolve( (Object[]) jdbcValueExtractor().extract( statement, paramName, session ), session );
|
||||
}
|
||||
|
||||
private Object resolve(Object[] value, SharedSessionContractImplementor session) throws HibernateException {
|
||||
final EmbeddableInstantiator instantiator = mappingModelPart.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
.getInstantiator();
|
||||
return instantiator.instantiate( () -> value, session.getFactory() );
|
||||
return instantiator().instantiate( () -> value, session.getFactory() );
|
||||
}
|
||||
|
||||
private EmbeddableMappingType embeddableTypeDescriptor() {
|
||||
return mappingModelPart.getEmbeddableTypeDescriptor();
|
||||
}
|
||||
|
||||
private ValueExtractor<?> jdbcValueExtractor() {
|
||||
return embeddableTypeDescriptor().getAggregateMapping().getJdbcMapping().getJdbcValueExtractor();
|
||||
}
|
||||
|
||||
private EmbeddableInstantiator instantiator() {
|
||||
return embeddableTypeDescriptor().getRepresentationStrategy().getInstantiator();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -842,12 +823,12 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
|
||||
@Override
|
||||
public SqmExpressible<?> resolveExpressible(SessionFactoryImplementor sessionFactory) {
|
||||
return sessionFactory.getRuntimeMetamodels().getJpaMetamodel().embeddable( getReturnedClass() );
|
||||
return sessionFactory.getJpaMetamodel().embeddable( getReturnedClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectMappingModelPart(EmbeddableValuedModelPart part, MappingModelCreationProcess process) {
|
||||
this.mappingModelPart = part;
|
||||
mappingModelPart = part;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue