📄 annotationbinder.java
字号:
); } //try to find class level generators HashMap<String, IdGenerator> classGenerators = buildLocalGenerators( annotatedClass, mappings ); // check properties List<PropertyData> elements = getElementsToProcess( clazzToProcess, inheritanceStatePerClass, propertyHolder, entityBinder, mappings ); if ( elements == null ) { throw new AnnotationException( "No identifier specified for entity: " + propertyHolder.getEntityName() ); } final boolean subclassAndSingleTableStrategy = inheritanceState.type == InheritanceType.SINGLE_TABLE && inheritanceState.hasParents; //process idclass if any Set<String> idProperties = new HashSet<String>(); IdClass idClass = null; if ( !inheritanceState.hasParents ) { //look for idClass XClass current = inheritanceState.clazz; InheritanceState state = inheritanceState; do { current = state.clazz; if ( current.isAnnotationPresent( IdClass.class ) ) { idClass = current.getAnnotation( IdClass.class ); break; } state = InheritanceState.getSuperclassInheritanceState( current, inheritanceStatePerClass, mappings.getReflectionManager() ); } while ( state != null ); } if ( idClass != null ) { XClass compositeClass = mappings.getReflectionManager().toXClass( idClass.value() ); boolean isComponent = true; boolean propertyAnnotated = entityBinder.isPropertyAnnotated( compositeClass ); String propertyAccessor = entityBinder.getPropertyAccessor( compositeClass ); String generatorType = "assigned"; String generator = BinderHelper.ANNOTATION_STRING_DEFAULT; PropertyData inferredData = new PropertyPreloadedData( entityBinder.getPropertyAccessor(), "id", compositeClass ); HashMap<String, IdGenerator> localGenerators = new HashMap<String, IdGenerator>(); boolean ignoreIdAnnotations = entityBinder.isIgnoreIdAnnotations(); entityBinder.setIgnoreIdAnnotations( true ); bindId( generatorType, generator, inferredData, null, propertyHolder, localGenerators, isComponent, propertyAnnotated, propertyAccessor, entityBinder, null, true, false, mappings ); inferredData = new PropertyPreloadedData( propertyAccessor, "_identifierMapper", compositeClass ); Component mapper = fillComponent( propertyHolder, inferredData, propertyAnnotated, propertyAccessor, false, entityBinder, true, true, false, mappings ); entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations ); persistentClass.setIdentifierMapper( mapper ); Property property = new Property(); property.setName( "_identifierMapper" ); property.setNodeName( "id" ); property.setUpdateable( false ); property.setInsertable( false ); property.setValue( mapper ); property.setPropertyAccessorName( "embedded" ); persistentClass.addProperty( property ); entityBinder.setIgnoreIdAnnotations( true ); Iterator properties = mapper.getPropertyIterator(); while ( properties.hasNext() ) { idProperties.add( ( (Property) properties.next() ).getName() ); } } Set<String> missingIdProperties = new HashSet<String>( idProperties ); for (PropertyData propertyAnnotatedElement : elements) { String propertyName = propertyAnnotatedElement.getPropertyName(); if ( !idProperties.contains( propertyName ) ) { processElementAnnotations( propertyHolder, subclassAndSingleTableStrategy ? Nullability.FORCED_NULL : Nullability.NO_CONSTRAINT, propertyAnnotatedElement.getProperty(), propertyAnnotatedElement, classGenerators, entityBinder, false, false, false, mappings ); } else { missingIdProperties.remove( propertyName ); } } if ( missingIdProperties.size() != 0 ) { StringBuilder missings = new StringBuilder(); for (String property : missingIdProperties) { missings.append( property ).append( ", " ); } throw new AnnotationException( "Unable to find properties (" + missings.substring( 0, missings.length() - 2 ) + ") in entity annotated with @IdClass:" + persistentClass.getEntityName() ); } if ( !inheritanceState.hasParents ) { final RootClass rootClass = (RootClass) persistentClass; mappings.addSecondPass( new CreateKeySecondPass( rootClass ) ); } else { superEntity.addSubclass( (Subclass) persistentClass ); } mappings.addClass( persistentClass ); //Process secondary tables and complementary definitions (ie o.h.a.Table) mappings.addSecondPass( new SecondaryTableSecondPass( entityBinder, propertyHolder, annotatedClass ) ); //add process complementary Table definition (index & all) entityBinder.processComplementaryTableDefinitions( annotatedClass.getAnnotation( org.hibernate.annotations.Table.class ) ); entityBinder.processComplementaryTableDefinitions( annotatedClass.getAnnotation( org.hibernate.annotations.Tables.class ) ); } /** * Get the annotated elements * Guess the annotated element from @Id or @EmbeddedId presence * Change EntityBinder by side effect */ private static List<PropertyData> getElementsToProcess( XClass clazzToProcess, Map<XClass, InheritanceState> inheritanceStatePerClass, PropertyHolder propertyHolder, EntityBinder entityBinder, ExtendedMappings mappings ) { InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess ); List<XClass> classesToProcess = orderClassesToBeProcessed( clazzToProcess, inheritanceStatePerClass, inheritanceState, mappings ); List<PropertyData> elements = new ArrayList<PropertyData>(); int deep = classesToProcess.size(); boolean hasIdentifier = false; assert !inheritanceState.isEmbeddableSuperclass; Boolean isExplicitPropertyAnnotated = null; String explicitAccessType = null; if ( inheritanceState.hasParents ) { InheritanceState superEntityState = InheritanceState.getSuperEntityInheritanceState( clazzToProcess, inheritanceStatePerClass, mappings.getReflectionManager() ); isExplicitPropertyAnnotated = superEntityState != null ? superEntityState.isPropertyAnnotated : null; explicitAccessType = superEntityState != null ? superEntityState.accessType : null; } else { AccessType access = clazzToProcess.getAnnotation( AccessType.class ); explicitAccessType = access != null ? access.value() : null; if ( "property".equals( explicitAccessType ) ) { isExplicitPropertyAnnotated = Boolean.TRUE; } else if ( "field".equals( explicitAccessType ) ) { isExplicitPropertyAnnotated = Boolean.FALSE; } } Boolean isPropertyAnnotated = isExplicitPropertyAnnotated == null ? Boolean.TRUE : //default to property and fallback if needed isExplicitPropertyAnnotated; String accessType = explicitAccessType != null ? explicitAccessType : "property"; /* * delay the exception in case field access is used */ AnnotationException exceptionWhileWalkingElements = null; try { for (int index = 0; index < deep; index++) { XClass clazz = classesToProcess.get( index ); boolean currentHasIdentifier = addElementsOfAClass( elements, propertyHolder, isPropertyAnnotated, accessType, clazz, mappings ); hasIdentifier = hasIdentifier || currentHasIdentifier; } } catch ( AnnotationException e ) { exceptionWhileWalkingElements = e; } //TODO remember why it should be !inheritanceState.hasParents if ( !hasIdentifier && !inheritanceState.hasParents ) { if ( isExplicitPropertyAnnotated != null ) { //the original exception is legitimate if ( exceptionWhileWalkingElements != null) throw exceptionWhileWalkingElements; return null; //explicit but no @Id: the upper layer will raise an exception } isPropertyAnnotated = !isPropertyAnnotated; accessType = "field"; elements.clear(); for (int index = 0; index < deep; index++) { XClass clazz = classesToProcess.get( index ); boolean currentHasIdentifier = addElementsOfAClass( elements, propertyHolder, isPropertyAnnotated, accessType, clazz, mappings ); hasIdentifier = hasIdentifier || currentHasIdentifier; } } //the field show no id, fallback tot he original exception if (!hasIdentifier && exceptionWhileWalkingElements != null) throw exceptionWhileWalkingElements; //TODO set the access type here? entityBinder.setPropertyAnnotated( isPropertyAnnotated ); entityBinder.setPropertyAccessor( accessType ); inheritanceState.isPropertyAnnotated = isPropertyAnnotated; inheritanceState.accessType = accessType; return hasIdentifier || inheritanceState.hasParents ? elements : null; } private static List<XClass> orderClassesToBeProcessed( XClass annotatedClass, Map<XClass, InheritanceState> inheritanceStatePerClass, InheritanceState inheritanceState, ExtendedMappings mappings ) { //ordered to allow proper messages on properties subclassing List<XClass> classesToProcess = new ArrayList<XClass>(); XClass currentClassInHierarchy = annotatedClass; InheritanceState superclassState; do { classesToProcess.add( 0, currentClassInHierarchy ); XClass superClass = currentClassInHierarchy; do { superClass = superClass.getSuperclass(); superclassState = inheritanceStatePerClass.get( superClass ); } while ( superClass != null && !mappings.getReflectionManager() .equals( superClass, Object.class ) && superclassState == null ); currentClassInHierarchy = superClass; } while ( superclassState != null && superclassState.isEmbeddableSuperclass ); return classesToProcess; } private static void bindFilterDefs(XAnnotatedElement annotatedElement, ExtendedMappings mappings) { FilterDef defAnn = annotatedElement.getAnnotation( FilterDef.class ); FilterDefs defsAnn = annotatedElement.getAnnotation( FilterDefs.class ); if ( defAnn != null ) { bindFilterDef( defAnn, mappings ); } if ( defsAnn != null ) { for (FilterDef def : defsAnn.value()) { bindFilterDef( def, mappings ); } } } private static void bindFilterDef(FilterDef defAnn, ExtendedMappings mappings) { Map<String, org.hibernate.type.Type> params = new HashMap<String, org.hibernate.type.Type>(); for (ParamDef param : defAnn.parameters()) { params.put( param.name(), TypeFactory.heuristicType( param.type() ) ); } FilterDefinition def = new FilterDefinition( defAnn.name(), defAnn.defaultCondition(), params ); if ( log.isInfoEnabled() ) log.info( "Binding filter definition: " + def.getFilterName() ); mappings.addFilterDefinition( def ); } private static void bindTypeDefs(XAnnotatedElement annotatedElement, ExtendedMappings mappings) { TypeDef defAnn = annotatedElement.getAnnotation( TypeDef.class ); TypeDefs defsAnn = annotatedElement.getAnnotation( TypeDefs.class ); if ( defAnn != null ) { bindTypeDef( defAnn, mappings ); } if ( defsAnn != null ) { for (TypeDef def : defsAnn.value()) { bindTypeDef( def, mappings ); } } } private static void bindTypeDef(TypeDef defAnn, ExtendedMappings mappings) { Properties params = new Properties(); for (Parameter param : defAnn.parameters()) { params.setProperty( param.name(), param.value() ); } if ( log.isInfoEnabled() ) log.info( "Binding type definition: " + defAnn.name() ); mappings.addTypeDef( defAnn.name(), defAnn.typeClass().getName(), params ); } private static void bindDiscriminatorToPersistentClass( RootClass rootClass, Ejb3DiscriminatorColumn discriminatorColumn, Map<String, Join> secondaryTables, PropertyHolder propertyHolder ) { if ( rootClass.getDiscriminator() == null ) { if ( discriminatorColumn == null ) { throw new AssertionFailure( "discriminator column should have been built" ); } discriminatorColumn.setJoins( secondaryTables ); discriminatorColumn.setPropertyHolder( propertyHolder ); SimpleValue discrim = new SimpleValue( rootClass.getTable() ); rootClass.setDiscriminator( discrim ); discriminatorColumn.linkWithValue( discrim ); discrim.setTypeName( discriminatorColumn.getDiscriminatorTypeName() );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -