HHH-12569 - Fix ordered inserts constraint violation when using a OneToOne with a JoinColumn.

This commit is contained in:
Chris Cranford 2018-05-17 15:58:06 -04:00
parent 3c3dc88283
commit de44e4180d
1 changed files with 20 additions and 18 deletions

View File

@ -60,7 +60,7 @@ import org.hibernate.type.Type;
* *
* The ActionQueue holds the DML operations queued as part of a session's transactional-write-behind semantics. The * 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. * DML operations are queued here until a flush forces them to be executed against the database.
* *
* @author Steve Ebersole * @author Steve Ebersole
* @author Gail Badner * @author Gail Badner
* @author Anton Marsden * @author Anton Marsden
@ -90,7 +90,7 @@ public class ActionQueue {
private ExecutableList<CollectionUpdateAction> collectionUpdates; private ExecutableList<CollectionUpdateAction> collectionUpdates;
private ExecutableList<QueuedOperationCollectionAction> collectionQueuedOps; private ExecutableList<QueuedOperationCollectionAction> collectionQueuedOps;
private ExecutableList<CollectionRemoveAction> collectionRemovals; private ExecutableList<CollectionRemoveAction> collectionRemovals;
// TODO: The removeOrphan concept is a temporary "hack" for HHH-6484. This should be removed once action/task // TODO: The removeOrphan concept is a temporary "hack" for HHH-6484. This should be removed once action/task
// ordering is improved. // ordering is improved.
private ExecutableList<OrphanRemovalAction> orphanRemovals; private ExecutableList<OrphanRemovalAction> orphanRemovals;
@ -220,7 +220,7 @@ public class ActionQueue {
/** /**
* Constructs an action queue bound to the given session. * Constructs an action queue bound to the given session.
* *
* @param session The session "owning" this queue. * @param session The session "owning" this queue.
*/ */
public ActionQueue(SessionImplementor session) { public ActionQueue(SessionImplementor session) {
@ -413,7 +413,7 @@ public class ActionQueue {
/** /**
* Are there unresolved entity insert actions that depend on non-nullable associations with a transient entity? * Are there unresolved entity insert actions that depend on non-nullable associations with a transient entity?
* *
* @return true, if there are unresolved entity insert actions that depend on non-nullable associations with a * @return true, if there are unresolved entity insert actions that depend on non-nullable associations with a
* transient entity; false, otherwise * transient entity; false, otherwise
*/ */
@ -425,7 +425,7 @@ public class ActionQueue {
* Throws {@link org.hibernate.PropertyValueException} if there are any unresolved entity insert actions that depend * Throws {@link org.hibernate.PropertyValueException} if there are any unresolved entity insert actions that depend
* on non-nullable associations with a transient entity. This method should be called on completion of an operation * on non-nullable associations with a transient entity. This method should be called on completion of an operation
* (after all cascades are completed) that saves an entity. * (after all cascades are completed) that saves an entity.
* *
* @throws org.hibernate.PropertyValueException if there are any unresolved entity insert actions; * @throws org.hibernate.PropertyValueException if there are any unresolved entity insert actions;
* {@link org.hibernate.PropertyValueException#getEntityName()} and * {@link org.hibernate.PropertyValueException#getEntityName()} and
* {@link org.hibernate.PropertyValueException#getPropertyName()} will return the entity name and property value for * {@link org.hibernate.PropertyValueException#getPropertyName()} will return the entity name and property value for
@ -453,7 +453,7 @@ public class ActionQueue {
/** /**
* Perform all currently queued entity-insertion actions. * Perform all currently queued entity-insertion actions.
* *
* @throws HibernateException error executing queued insertion actions. * @throws HibernateException error executing queued insertion actions.
*/ */
public void executeInserts() throws HibernateException { public void executeInserts() throws HibernateException {
@ -464,7 +464,7 @@ public class ActionQueue {
/** /**
* Perform all currently queued actions. * Perform all currently queued actions.
* *
* @throws HibernateException error executing queued actions. * @throws HibernateException error executing queued actions.
*/ */
public void executeActions() throws HibernateException { public void executeActions() throws HibernateException {
@ -482,7 +482,7 @@ public class ActionQueue {
/** /**
* Prepares the internal action queues for execution. * Prepares the internal action queues for execution.
* *
* @throws HibernateException error preparing actions. * @throws HibernateException error preparing actions.
*/ */
public void prepareActions() throws HibernateException { public void prepareActions() throws HibernateException {
@ -503,7 +503,7 @@ public class ActionQueue {
/** /**
* Performs cleanup of any held cache softlocks. * Performs cleanup of any held cache softlocks.
* *
* @param success Was the transaction successful. * @param success Was the transaction successful.
*/ */
public void afterTransactionCompletion(boolean success) { public void afterTransactionCompletion(boolean success) {
@ -538,7 +538,7 @@ public class ActionQueue {
/** /**
* Check whether the given tables/query-spaces are to be executed against given the currently queued actions. * Check whether the given tables/query-spaces are to be executed against given the currently queued actions.
* *
* @param tables The table/query-spaces to check. * @param tables The table/query-spaces to check.
* *
* @return {@code true} if we contain pending actions against any of the given tables; {@code false} otherwise. * @return {@code true} if we contain pending actions against any of the given tables; {@code false} otherwise.
@ -589,7 +589,7 @@ public class ActionQueue {
/** /**
* Perform {@link org.hibernate.action.spi.Executable#execute()} on each element of the list * Perform {@link org.hibernate.action.spi.Executable#execute()} on each element of the list
* *
* @param list The list of Executable elements to be performed * @param list The list of Executable elements to be performed
* *
* @throws HibernateException * @throws HibernateException
@ -651,7 +651,7 @@ public class ActionQueue {
/** /**
* This method is now called once per execution of an ExecutableList or once for execution of an Execution. * This method is now called once per execution of an ExecutableList or once for execution of an Execution.
* *
* @param spaces The spaces to invalidate * @param spaces The spaces to invalidate
*/ */
private void invalidateSpaces(String... spaces) { private void invalidateSpaces(String... spaces) {
@ -669,7 +669,7 @@ public class ActionQueue {
/** /**
* Returns a string representation of the object. * Returns a string representation of the object.
* *
* @return a string representation of the object. * @return a string representation of the object.
*/ */
@Override @Override
@ -858,7 +858,7 @@ public class ActionQueue {
/** /**
* Used by the owning session to explicitly control serialization of the action queue * Used by the owning session to explicitly control serialization of the action queue
* *
* @param oos The stream to which the action queue should get written * @param oos The stream to which the action queue should get written
* @throws IOException Indicates an error writing to the stream * @throws IOException Indicates an error writing to the stream
*/ */
@ -883,7 +883,7 @@ public class ActionQueue {
/** /**
* Used by the owning session to explicitly control deserialization of the action queue. * Used by the owning session to explicitly control deserialization of the action queue.
* *
* @param ois The stream from which to read the action queue * @param ois The stream from which to read the action queue
* @param session The session to which the action queue belongs * @param session The session to which the action queue belongs
* @return The deserialized action queue * @return The deserialized action queue
@ -1025,7 +1025,7 @@ public class ActionQueue {
* Sorts the insert actions using more hashes. * Sorts the insert actions using more hashes.
* </p> * </p>
* NOTE: this class is not thread-safe. * NOTE: this class is not thread-safe.
* *
* @author Jay Erb * @author Jay Erb
*/ */
private static class InsertActionSorter implements ExecutableList.Sorter<AbstractEntityInsertAction> { private static class InsertActionSorter implements ExecutableList.Sorter<AbstractEntityInsertAction> {
@ -1247,7 +1247,7 @@ public class ActionQueue {
/** /**
* Add parent and child entity names so that we know how to rearrange dependencies * Add parent and child entity names so that we know how to rearrange dependencies
* *
* @param action The action being sorted * @param action The action being sorted
* @param batchIdentifier The batch identifier of the entity affected by the action * @param batchIdentifier The batch identifier of the entity affected by the action
*/ */
@ -1272,7 +1272,9 @@ public class ActionQueue {
final String rootEntityName = action.getSession().getFactory().getMetamodel().entityPersister( entityName ).getRootEntityName(); final String rootEntityName = action.getSession().getFactory().getMetamodel().entityPersister( entityName ).getRootEntityName();
if ( entityType.isOneToOne() && OneToOneType.class.cast( entityType ).getForeignKeyDirection() == ForeignKeyDirection.TO_PARENT ) { if ( entityType.isOneToOne() && OneToOneType.class.cast( entityType ).getForeignKeyDirection() == ForeignKeyDirection.TO_PARENT ) {
batchIdentifier.getChildEntityNames().add( entityName ); if ( !entityType.isReferenceToPrimaryKey() ) {
batchIdentifier.getChildEntityNames().add( entityName );
}
if ( !rootEntityName.equals( entityName ) ) { if ( !rootEntityName.equals( entityName ) ) {
batchIdentifier.getChildEntityNames().add( rootEntityName ); batchIdentifier.getChildEntityNames().add( rootEntityName );
} }