1 package org.hibernate.engine; 3 4 import java.util.Iterator ; 5 6 import org.hibernate.HibernateException; 7 import org.hibernate.PropertyValueException; 8 import org.hibernate.intercept.LazyPropertyInitializer; 9 import org.hibernate.persister.entity.EntityPersister; 10 import org.hibernate.type.AbstractComponentType; 11 import org.hibernate.type.CollectionType; 12 import org.hibernate.type.Type; 13 14 19 public final class Nullability { 20 21 private final SessionImplementor session; 22 23 public Nullability(SessionImplementor session) { 24 this.session = session; 25 } 26 35 public void checkNullability( 36 final Object [] values, 37 final EntityPersister persister, 38 final boolean isUpdate) 39 throws PropertyValueException, HibernateException { 40 41 58 59 final boolean[] nullability = persister.getPropertyNullability(); 60 final boolean[] checkability = isUpdate ? 61 persister.getPropertyUpdateability() : 62 persister.getPropertyInsertability(); 63 final Type[] propertyTypes = persister.getPropertyTypes(); 64 65 for ( int i = 0; i < values.length; i++ ) { 66 67 if ( checkability[i] && values[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY ) { 68 final Object value = values[i]; 69 if ( !nullability[i] && value == null ) { 70 71 throw new PropertyValueException( 73 "not-null property references a null or transient value", 74 persister.getEntityName(), 75 persister.getPropertyNames()[i] 76 ); 77 78 } 79 else if ( value != null ) { 80 81 String breakProperties = checkSubElementsNullability( propertyTypes[i], value ); 83 if ( breakProperties != null ) { 84 throw new PropertyValueException( 85 "not-null property references a null or transient value", 86 persister.getEntityName(), 87 buildPropertyPath( persister.getPropertyNames()[i], breakProperties ) 88 ); 89 } 90 91 } 92 } 93 94 } 95 } 96 97 107 private String checkSubElementsNullability(final Type propertyType, final Object value) 108 throws HibernateException { 109 if ( propertyType.isComponentType() ) { 111 return checkComponentNullability( value, (AbstractComponentType) propertyType ); 112 } 113 else if ( propertyType.isCollectionType() ) { 114 115 CollectionType collectionType = (CollectionType) propertyType; 117 Type collectionElementType = collectionType.getElementType( session.getFactory() ); 118 if ( collectionElementType.isComponentType() ) { 119 121 AbstractComponentType componentType = (AbstractComponentType) collectionElementType; 122 Iterator iter = CascadingAction.getLoadedElementsIterator(session, collectionType, value); 123 while ( iter.hasNext() ) { 124 Object compValue = iter.next(); 125 if (compValue != null) { 126 return checkComponentNullability(compValue, componentType); 127 } 128 } 129 } 130 } 131 return null; 132 } 133 134 144 private String checkComponentNullability(final Object value, final AbstractComponentType compType) 145 throws HibernateException { 146 149 boolean[] nullability = compType.getPropertyNullability(); 150 if ( nullability!=null ) { 151 final Object [] values = compType.getPropertyValues( value, session.getEntityMode() ); 153 final Type[] propertyTypes = compType.getSubtypes(); 154 for ( int i=0; i<values.length; i++ ) { 155 final Object subvalue = values[i]; 156 if ( !nullability[i] && subvalue==null ) { 157 return compType.getPropertyNames()[i]; 158 } 159 else if ( subvalue != null ) { 160 String breakProperties = checkSubElementsNullability( propertyTypes[i], subvalue ); 161 if ( breakProperties != null ) { 162 return buildPropertyPath( compType.getPropertyNames()[i], breakProperties ); 163 } 164 } 165 } 166 } 167 return null; 168 } 169 170 178 private static String buildPropertyPath(String parent, String child) { 179 return new StringBuffer ( parent.length() + child.length() + 1 ) 180 .append(parent).append('.').append(child).toString(); 181 } 182 183 } 184 | Popular Tags |