use of org.hibernate.engine.internal.NonNullableTransientDependencies in project hibernate-orm by hibernate.
the class UnresolvedEntityInsertActions method resolveDependentActions.
/**
* Resolve any dependencies on {@code managedEntity}.
*
* @param managedEntity - the managed entity name
* @param session - the session
*
* @return the insert actions that depended only on the specified entity.
*
* @throws IllegalArgumentException if {@code managedEntity} did not have managed or read-only status.
*/
@SuppressWarnings({ "unchecked" })
public Set<AbstractEntityInsertAction> resolveDependentActions(Object managedEntity, SessionImplementor session) {
final EntityEntry entityEntry = session.getPersistenceContext().getEntry(managedEntity);
if (entityEntry.getStatus() != Status.MANAGED && entityEntry.getStatus() != Status.READ_ONLY) {
throw new IllegalArgumentException("EntityEntry did not have status MANAGED or READ_ONLY: " + entityEntry);
}
final boolean traceEnabled = LOG.isTraceEnabled();
// Find out if there are any unresolved insertions that are waiting for the
// specified entity to be resolved.
final Set<AbstractEntityInsertAction> dependentActions = dependentActionsByTransientEntity.remove(managedEntity);
if (dependentActions == null) {
if (traceEnabled) {
LOG.tracev("No unresolved entity inserts that depended on [{0}]", MessageHelper.infoString(entityEntry.getEntityName(), entityEntry.getId()));
}
// NOTE EARLY EXIT!
return Collections.emptySet();
}
final Set<AbstractEntityInsertAction> resolvedActions = new IdentitySet();
if (traceEnabled) {
LOG.tracev("Unresolved inserts beforeQuery resolving [{0}]: [{1}]", MessageHelper.infoString(entityEntry.getEntityName(), entityEntry.getId()), toString());
}
for (AbstractEntityInsertAction dependentAction : dependentActions) {
if (traceEnabled) {
LOG.tracev("Resolving insert [{0}] dependency on [{1}]", MessageHelper.infoString(dependentAction.getEntityName(), dependentAction.getId()), MessageHelper.infoString(entityEntry.getEntityName(), entityEntry.getId()));
}
final NonNullableTransientDependencies dependencies = dependenciesByAction.get(dependentAction);
dependencies.resolveNonNullableTransientEntity(managedEntity);
if (dependencies.isEmpty()) {
if (traceEnabled) {
LOG.tracev("Resolving insert [{0}] (only depended on [{1}])", dependentAction, MessageHelper.infoString(entityEntry.getEntityName(), entityEntry.getId()));
}
// dependentAction only depended on managedEntity..
dependenciesByAction.remove(dependentAction);
resolvedActions.add(dependentAction);
}
}
if (traceEnabled) {
LOG.tracev("Unresolved inserts afterQuery resolving [{0}]: [{1}]", MessageHelper.infoString(entityEntry.getEntityName(), entityEntry.getId()), toString());
}
return resolvedActions;
}
use of org.hibernate.engine.internal.NonNullableTransientDependencies in project hibernate-orm by hibernate.
the class ActionQueue method addInsertAction.
private void addInsertAction(AbstractEntityInsertAction insert) {
if (insert.isEarlyInsert()) {
// For early inserts, must execute inserts beforeQuery finding non-nullable transient entities.
// TODO: find out why this is necessary
LOG.tracev("Executing inserts beforeQuery finding non-nullable transient entities for early insert: [{0}]", insert);
executeInserts();
}
NonNullableTransientDependencies nonNullableTransientDependencies = insert.findNonNullableTransientEntities();
if (nonNullableTransientDependencies == null) {
LOG.tracev("Adding insert with no non-nullable, transient entities: [{0}]", insert);
addResolvedEntityInsertAction(insert);
} else {
if (LOG.isTraceEnabled()) {
LOG.tracev("Adding insert with non-nullable, transient entities; insert=[{0}], dependencies=[{1}]", insert, nonNullableTransientDependencies.toLoggableString(insert.getSession()));
}
if (unresolvedInsertions == null) {
unresolvedInsertions = new UnresolvedEntityInsertActions();
}
unresolvedInsertions.addUnresolvedEntityInsertAction(insert, nonNullableTransientDependencies);
}
}
use of org.hibernate.engine.internal.NonNullableTransientDependencies in project hibernate-orm by hibernate.
the class UnresolvedEntityInsertActions method checkNoUnresolvedActionsAfterOperation.
/**
* 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 (afterQuery all cascades are completed) that saves an entity.
*
* @throws org.hibernate.PropertyValueException if there are any unresolved entity
* insert actions; {@link org.hibernate.PropertyValueException#getEntityName()}
* and {@link org.hibernate.PropertyValueException#getPropertyName()} will
* return the entity name and property value for the first unresolved
* entity insert action.
*/
public void checkNoUnresolvedActionsAfterOperation() throws PropertyValueException {
if (isEmpty()) {
LOG.trace("No entity insert actions have non-nullable, transient entity dependencies.");
} else {
final AbstractEntityInsertAction firstDependentAction = dependenciesByAction.keySet().iterator().next();
logCannotResolveNonNullableTransientDependencies(firstDependentAction.getSession());
final NonNullableTransientDependencies nonNullableTransientDependencies = dependenciesByAction.get(firstDependentAction);
final Object firstTransientDependency = nonNullableTransientDependencies.getNonNullableTransientEntities().iterator().next();
final String firstPropertyPath = nonNullableTransientDependencies.getNonNullableTransientPropertyPaths(firstTransientDependency).iterator().next();
throw new TransientPropertyValueException("Not-null property references a transient value - transient instance must be saved beforeQuery current operation", firstDependentAction.getSession().guessEntityName(firstTransientDependency), firstDependentAction.getEntityName(), firstPropertyPath);
}
}
use of org.hibernate.engine.internal.NonNullableTransientDependencies in project hibernate-orm by hibernate.
the class UnresolvedEntityInsertActions method toString.
@Override
public String toString() {
final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
for (Map.Entry<AbstractEntityInsertAction, NonNullableTransientDependencies> entry : dependenciesByAction.entrySet()) {
final AbstractEntityInsertAction insert = entry.getKey();
final NonNullableTransientDependencies dependencies = entry.getValue();
sb.append("[insert=").append(insert).append(" dependencies=[").append(dependencies.toLoggableString(insert.getSession())).append("]");
}
sb.append(']');
return sb.toString();
}
Aggregations