|
9 | 9 | import org.hibernate.HibernateException;
|
10 | 10 | import org.hibernate.TransientObjectException;
|
11 | 11 | import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
| 12 | +import org.hibernate.engine.internal.NonNullableTransientDependencies; |
12 | 13 | import org.hibernate.engine.spi.EntityEntry;
|
13 | 14 | import org.hibernate.engine.spi.SelfDirtinessTracker;
|
14 | 15 | import org.hibernate.engine.spi.SessionImplementor;
|
| 16 | +import org.hibernate.engine.spi.SharedSessionContractImplementor; |
15 | 17 | import org.hibernate.internal.util.StringHelper;
|
16 | 18 | import org.hibernate.persister.entity.EntityPersister;
|
17 | 19 | import org.hibernate.proxy.HibernateProxy;
|
@@ -359,6 +361,92 @@ public static CompletionStage<Object> getEntityIdentifierIfNotUnsaved(
|
359 | 361 | }
|
360 | 362 | }
|
361 | 363 |
|
| 364 | + public static CompletionStage<NonNullableTransientDependencies> findNonNullableTransientEntities( |
| 365 | + String entityName, |
| 366 | + Object entity, |
| 367 | + Object[] values, |
| 368 | + boolean isEarlyInsert, |
| 369 | + SharedSessionContractImplementor session) { |
| 370 | + |
| 371 | + final EntityPersister persister = session.getEntityPersister( entityName, entity ); |
| 372 | + final Type[] types = persister.getPropertyTypes(); |
| 373 | + final Nullifier nullifier = new Nullifier( entity, false, isEarlyInsert, (SessionImplementor) session, persister ); |
| 374 | + final String[] propertyNames = persister.getPropertyNames(); |
| 375 | + final boolean[] nullability = persister.getPropertyNullability(); |
| 376 | + final NonNullableTransientDependencies nonNullableTransientEntities = new NonNullableTransientDependencies(); |
| 377 | + |
| 378 | + return loop( 0, types.length, |
| 379 | + i -> collectNonNullableTransientEntities( |
| 380 | + nullifier, |
| 381 | + values[i], |
| 382 | + propertyNames[i], |
| 383 | + types[i], |
| 384 | + nullability[i], |
| 385 | + session, |
| 386 | + nonNullableTransientEntities |
| 387 | + ) |
| 388 | + ).thenApply( r -> nonNullableTransientEntities.isEmpty() ? null : nonNullableTransientEntities ); |
| 389 | + } |
| 390 | + |
| 391 | + private static CompletionStage<Void> collectNonNullableTransientEntities( |
| 392 | + Nullifier nullifier, |
| 393 | + Object value, |
| 394 | + String propertyName, |
| 395 | + Type type, |
| 396 | + boolean isNullable, |
| 397 | + SharedSessionContractImplementor session, |
| 398 | + NonNullableTransientDependencies nonNullableTransientEntities) { |
| 399 | + |
| 400 | + if ( value == null ) { |
| 401 | + return voidFuture(); |
| 402 | + } |
| 403 | + |
| 404 | + if ( type.isEntityType() ) { |
| 405 | + final EntityType entityType = (EntityType) type; |
| 406 | + if ( !isNullable && !entityType.isOneToOne() ) { |
| 407 | + return nullifier |
| 408 | + .isNullifiable( entityType.getAssociatedEntityName(), value ) |
| 409 | + .thenAccept( isNullifiable -> { |
| 410 | + if ( isNullifiable ) { |
| 411 | + nonNullableTransientEntities.add( propertyName, value ); |
| 412 | + } |
| 413 | + } ); |
| 414 | + } |
| 415 | + } |
| 416 | + else if ( type.isAnyType() ) { |
| 417 | + if ( !isNullable ) { |
| 418 | + return nullifier |
| 419 | + .isNullifiable( null, value ) |
| 420 | + .thenAccept( isNullifiable -> { |
| 421 | + if ( isNullifiable ) { |
| 422 | + nonNullableTransientEntities.add( propertyName, value ); |
| 423 | + } |
| 424 | + } ); |
| 425 | + }; |
| 426 | + } |
| 427 | + else if ( type.isComponentType() ) { |
| 428 | + final CompositeType actype = (CompositeType) type; |
| 429 | + final boolean[] subValueNullability = actype.getPropertyNullability(); |
| 430 | + if ( subValueNullability != null ) { |
| 431 | + final String[] subPropertyNames = actype.getPropertyNames(); |
| 432 | + final Object[] subvalues = actype.getPropertyValues( value, session ); |
| 433 | + final Type[] subtypes = actype.getSubtypes(); |
| 434 | + return loop( 0, subtypes.length, |
| 435 | + i -> collectNonNullableTransientEntities( |
| 436 | + nullifier, |
| 437 | + subvalues[i], |
| 438 | + subPropertyNames[i], |
| 439 | + subtypes[i], |
| 440 | + subValueNullability[i], |
| 441 | + session, |
| 442 | + nonNullableTransientEntities |
| 443 | + ) |
| 444 | + ); |
| 445 | + } |
| 446 | + } |
| 447 | + |
| 448 | + return voidFuture(); |
| 449 | + } |
362 | 450 |
|
363 | 451 | /**
|
364 | 452 | * Disallow instantiation
|
|
0 commit comments