mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-27 14:30:16 +00:00
HHH-8276 - Fix AnyType handling during Nullability checking
This commit is contained in:
parent
479b873f5b
commit
edc4a04a63
@ -139,37 +139,23 @@ else if ( value != null ) {
|
|||||||
* @throws HibernateException error while getting subcomponent values
|
* @throws HibernateException error while getting subcomponent values
|
||||||
*/
|
*/
|
||||||
private String checkSubElementsNullability(Type propertyType, Object value) throws HibernateException {
|
private String checkSubElementsNullability(Type propertyType, Object value) throws HibernateException {
|
||||||
// IMPL NOTE : we currently skip checking "any" and "many to any" mappings. This is not the best solution.
|
|
||||||
//
|
|
||||||
// The problem I ran into with performing the checks on "any" and "many to any" mappings had to do with
|
|
||||||
// cascaded saves of transient associated entities not yet having assigned the identifier (this was
|
|
||||||
// specifically in the "many to any" case).
|
|
||||||
|
|
||||||
if ( propertyType.isAnyType() ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( propertyType.isComponentType() ) {
|
if ( propertyType.isComponentType() ) {
|
||||||
return checkComponentNullability( value, (CompositeType) propertyType );
|
return checkComponentNullability( value, (CompositeType) propertyType );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( propertyType.isCollectionType() ) {
|
if ( propertyType.isCollectionType() ) {
|
||||||
//persistent collections may have components
|
// persistent collections may have components
|
||||||
final CollectionType collectionType = (CollectionType) propertyType;
|
final CollectionType collectionType = (CollectionType) propertyType;
|
||||||
final Type collectionElementType = collectionType.getElementType( session.getFactory() );
|
final Type collectionElementType = collectionType.getElementType( session.getFactory() );
|
||||||
|
|
||||||
if ( collectionElementType.isAnyType() ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( collectionElementType.isComponentType() ) {
|
if ( collectionElementType.isComponentType() ) {
|
||||||
//check for all components values in the collection
|
// check for all components values in the collection
|
||||||
final CompositeType componentType = (CompositeType) collectionElementType;
|
final CompositeType componentType = (CompositeType) collectionElementType;
|
||||||
final Iterator itr = CascadingActions.getLoadedElementsIterator( session, collectionType, value );
|
final Iterator itr = CascadingActions.getLoadedElementsIterator( session, collectionType, value );
|
||||||
while ( itr.hasNext() ) {
|
while ( itr.hasNext() ) {
|
||||||
final Object compValue = itr.next();
|
final Object compositeElement = itr.next();
|
||||||
if ( compValue != null ) {
|
if ( compositeElement != null ) {
|
||||||
return checkComponentNullability( compValue, componentType );
|
return checkComponentNullability( compositeElement, componentType );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,29 +169,39 @@ private String checkSubElementsNullability(Type propertyType, Object value) thro
|
|||||||
* nullability or null if none
|
* nullability or null if none
|
||||||
*
|
*
|
||||||
* @param value component properties
|
* @param value component properties
|
||||||
* @param compType component not-nullable type
|
* @param compositeType component not-nullable type
|
||||||
*
|
*
|
||||||
* @return property path
|
* @return property path
|
||||||
* @throws HibernateException error while getting subcomponent values
|
* @throws HibernateException error while getting subcomponent values
|
||||||
*/
|
*/
|
||||||
private String checkComponentNullability(Object value, CompositeType compType) throws HibernateException {
|
private String checkComponentNullability(Object value, CompositeType compositeType) throws HibernateException {
|
||||||
/* will check current level if some of them are not null
|
// IMPL NOTE : we currently skip checking "any" and "many to any" mappings.
|
||||||
* or sublevels if they exist
|
//
|
||||||
*/
|
// This is not the best solution. But atm there is a mismatch between AnyType#getPropertyNullability
|
||||||
final boolean[] nullability = compType.getPropertyNullability();
|
// and the fact that cascaded-saves for "many to any" mappings are not performed until after this nullability
|
||||||
|
// check. So the nullability check fails for transient entity elements with generated identifiers because
|
||||||
|
// the identifier is not yet generated/assigned (is null)
|
||||||
|
//
|
||||||
|
// The more correct fix would be to cascade saves of the many-to-any elements before the Nullability checking
|
||||||
|
|
||||||
|
if ( compositeType.isAnyType() ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean[] nullability = compositeType.getPropertyNullability();
|
||||||
if ( nullability != null ) {
|
if ( nullability != null ) {
|
||||||
//do the test
|
//do the test
|
||||||
final Object[] subValues = compType.getPropertyValues( value, session );
|
final Object[] subValues = compositeType.getPropertyValues( value, session );
|
||||||
final Type[] propertyTypes = compType.getSubtypes();
|
final Type[] propertyTypes = compositeType.getSubtypes();
|
||||||
for ( int i = 0; i < subValues.length; i++ ) {
|
for ( int i = 0; i < subValues.length; i++ ) {
|
||||||
final Object subValue = subValues[i];
|
final Object subValue = subValues[i];
|
||||||
if ( !nullability[i] && subValue==null ) {
|
if ( !nullability[i] && subValue==null ) {
|
||||||
return compType.getPropertyNames()[i];
|
return compositeType.getPropertyNames()[i];
|
||||||
}
|
}
|
||||||
else if ( subValue != null ) {
|
else if ( subValue != null ) {
|
||||||
final String breakProperties = checkSubElementsNullability( propertyTypes[i], subValue );
|
final String breakProperties = checkSubElementsNullability( propertyTypes[i], subValue );
|
||||||
if ( breakProperties != null ) {
|
if ( breakProperties != null ) {
|
||||||
return buildPropertyPath( compType.getPropertyNames()[i], breakProperties );
|
return buildPropertyPath( compositeType.getPropertyNames()[i], breakProperties );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user