hibernate3.6.10 注解配置添加表字段注释
如果使用的是xml方式配置,则使用comment即可:
<property name="name"  >
      <column name="name_col">
      <comment>我是注释</comment>
      </column>
    </property>
下面的方法是修改hibernate3.6.10源码、添加注解配置的处理信息:
- package org.hibernate.cfg;
 - import java.lang.annotation.ElementType;
 - import java.lang.annotation.Retention;
 - import java.lang.annotation.RetentionPolicy;
 - import java.lang.annotation.Target;
 - @Target({ElementType.TYPE,ElementType.FIELD})
 - @Retention(RetentionPolicy.RUNTIME)
 - public @interface Comment {
 - String value() default "";
 - }
 
- package org.hibernate.cfg;
 - import org.hibernate.annotations.common.reflection.XClass;
 - import org.hibernate.annotations.common.reflection.XProperty;
 - import org.hibernate.cfg.Ejb3Column;
 - import org.hibernate.mapping.PersistentClass;
 - public class CommentBinder {
 - public static void bindTableComment(XClass clazzToProcess, PersistentClass persistentClass) {
 - //System.out.println("处理表名注释!");
 - if (clazzToProcess.isAnnotationPresent(Comment.class)) {
 - String tableComment = clazzToProcess.getAnnotation(Comment.class).value();
 - persistentClass.getTable().setComment(tableComment);
 - }
 - }
 - public static void bindColumnComment(XProperty property, Ejb3Column[] columns) {
 - //System.out.println("处理多字段注释"+property+columns);
 - if (null != columns)
 - if (property.isAnnotationPresent(Comment.class)) {
 - String comment = property.getAnnotation(Comment.class).value();
 - for (Ejb3Column column : columns) {
 - column.getMappingColumn().setComment(comment);
 - }
 - }
 - }
 - public static void bindColumnComment(XProperty property, Ejb3Column column) {
 - //System.out.println("处理字段注释");
 - if (null != column)
 - if (property.isAnnotationPresent(Comment.class)) {
 - String comment = property.getAnnotation(Comment.class).value();
 - column.getMappingColumn().setComment(comment);
 - }
 - }
 - }
 
下面这个类路径不能变、覆盖hibernate对应的源码。
- /*
 - * Hibernate, Relational Persistence for Idiomatic Java
 - *
 - * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
 - * indicated by the @author tags or express copyright attribution
 - * statements applied by the authors. All third-party contributions are
 - * distributed under license by Red Hat Inc.
 - *
 - * This copyrighted material is made available to anyone wishing to use, modify,
 - * copy, or redistribute it subject to the terms and conditions of the GNU
 - * Lesser General Public License, as published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 - * for more details.
 - *
 - * You should have received a copy of the GNU Lesser General Public License
 - * along with this distribution; if not, write to:
 - * Free Software Foundation, Inc.
 - * 51 Franklin Street, Fifth Floor
 - * Boston, MA 02110-1301 USA
 - */
 - package org.hibernate.cfg;
 - import java.lang.annotation.Annotation;
 - import java.util.ArrayList;
 - import java.util.Arrays;
 - import java.util.Collection;
 - import java.util.EnumSet;
 - import java.util.HashMap;
 - import java.util.HashSet;
 - import java.util.Iterator;
 - import java.util.List;
 - import java.util.Map;
 - import java.util.Properties;
 - import java.util.Set;
 - import javax.persistence.Basic;
 - import javax.persistence.Cacheable;
 - import javax.persistence.CollectionTable;
 - import javax.persistence.Column;
 - import javax.persistence.DiscriminatorType;
 - import javax.persistence.DiscriminatorValue;
 - import javax.persistence.ElementCollection;
 - import javax.persistence.Embeddable;
 - import javax.persistence.Embedded;
 - import javax.persistence.EmbeddedId;
 - import javax.persistence.Entity;
 - import javax.persistence.FetchType;
 - import javax.persistence.GeneratedValue;
 - import javax.persistence.GenerationType;
 - import javax.persistence.Id;
 - import javax.persistence.IdClass;
 - import javax.persistence.InheritanceType;
 - import javax.persistence.JoinColumn;
 - import javax.persistence.JoinTable;
 - import javax.persistence.ManyToMany;
 - import javax.persistence.ManyToOne;
 - import javax.persistence.MapKey;
 - import javax.persistence.MapKeyColumn;
 - import javax.persistence.MapKeyJoinColumn;
 - import javax.persistence.MapKeyJoinColumns;
 - import javax.persistence.MappedSuperclass;
 - import javax.persistence.MapsId;
 - import javax.persistence.NamedNativeQueries;
 - import javax.persistence.NamedNativeQuery;
 - import javax.persistence.NamedQueries;
 - import javax.persistence.NamedQuery;
 - import javax.persistence.OneToMany;
 - import javax.persistence.OneToOne;
 - import javax.persistence.OrderColumn;
 - import javax.persistence.PrimaryKeyJoinColumn;
 - import javax.persistence.PrimaryKeyJoinColumns;
 - import javax.persistence.SequenceGenerator;
 - import javax.persistence.SharedCacheMode;
 - import javax.persistence.SqlResultSetMapping;
 - import javax.persistence.SqlResultSetMappings;
 - import javax.persistence.Table;
 - import javax.persistence.TableGenerator;
 - import javax.persistence.UniqueConstraint;
 - import javax.persistence.Version;
 - import org.slf4j.Logger;
 - import org.slf4j.LoggerFactory;
 - import org.hibernate.AnnotationException;
 - import org.hibernate.AssertionFailure;
 - import org.hibernate.EntityMode;
 - import org.hibernate.FetchMode;
 - import org.hibernate.MappingException;
 - import org.hibernate.annotations.BatchSize;
 - import org.hibernate.annotations.Cache;
 - import org.hibernate.annotations.CacheConcurrencyStrategy;
 - import org.hibernate.annotations.Cascade;
 - import org.hibernate.annotations.CascadeType;
 - import org.hibernate.annotations.Check;
 - import org.hibernate.annotations.CollectionId;
 - import org.hibernate.annotations.CollectionOfElements;
 - import org.hibernate.annotations.Columns;
 - import org.hibernate.annotations.DiscriminatorOptions;
 - import org.hibernate.annotations.Fetch;
 - import org.hibernate.annotations.FetchProfile;
 - import org.hibernate.annotations.FetchProfiles;
 - import org.hibernate.annotations.Filter;
 - import org.hibernate.annotations.FilterDef;
 - import org.hibernate.annotations.FilterDefs;
 - import org.hibernate.annotations.Filters;
 - import org.hibernate.annotations.ForceDiscriminator;
 - import org.hibernate.annotations.ForeignKey;
 - import org.hibernate.annotations.Formula;
 - import org.hibernate.annotations.GenericGenerator;
 - import org.hibernate.annotations.GenericGenerators;
 - import org.hibernate.annotations.Index;
 - import org.hibernate.annotations.LazyToOne;
 - import org.hibernate.annotations.LazyToOneOption;
 - import org.hibernate.annotations.ManyToAny;
 - import org.hibernate.annotations.MapKeyType;
 - import org.hibernate.annotations.NaturalId;
 - import org.hibernate.annotations.NotFound;
 - import org.hibernate.annotations.NotFoundAction;
 - import org.hibernate.annotations.OnDelete;
 - import org.hibernate.annotations.OnDeleteAction;
 - import org.hibernate.annotations.OrderBy;
 - import org.hibernate.annotations.ParamDef;
 - import org.hibernate.annotations.Parameter;
 - import org.hibernate.annotations.Parent;
 - import org.hibernate.annotations.Proxy;
 - import org.hibernate.annotations.Sort;
 - import org.hibernate.annotations.Source;
 - import org.hibernate.annotations.Tuplizer;
 - import org.hibernate.annotations.Tuplizers;
 - import org.hibernate.annotations.TypeDef;
 - import org.hibernate.annotations.TypeDefs;
 - import org.hibernate.annotations.Where;
 - import org.hibernate.annotations.common.reflection.ReflectionManager;
 - import org.hibernate.annotations.common.reflection.XAnnotatedElement;
 - import org.hibernate.annotations.common.reflection.XClass;
 - import org.hibernate.annotations.common.reflection.XMethod;
 - import org.hibernate.annotations.common.reflection.XPackage;
 - import org.hibernate.annotations.common.reflection.XProperty;
 - import org.hibernate.cache.RegionFactory;
 - import org.hibernate.cfg.annotations.CollectionBinder;
 - import org.hibernate.cfg.annotations.EntityBinder;
 - import org.hibernate.cfg.annotations.MapKeyColumnDelegator;
 - import org.hibernate.cfg.annotations.MapKeyJoinColumnDelegator;
 - import org.hibernate.cfg.annotations.Nullability;
 - import org.hibernate.cfg.annotations.PropertyBinder;
 - import org.hibernate.cfg.annotations.QueryBinder;
 - import org.hibernate.cfg.annotations.SimpleValueBinder;
 - import org.hibernate.cfg.annotations.TableBinder;
 - import org.hibernate.engine.FilterDefinition;
 - import org.hibernate.engine.Versioning;
 - import org.hibernate.id.MultipleHiLoPerTableGenerator;
 - import org.hibernate.id.PersistentIdentifierGenerator;
 - import org.hibernate.id.SequenceHiLoGenerator;
 - import org.hibernate.id.TableHiLoGenerator;
 - import org.hibernate.id.enhanced.SequenceStyleGenerator;
 - import org.hibernate.mapping.Any;
 - import org.hibernate.mapping.Component;
 - import org.hibernate.mapping.DependantValue;
 - import org.hibernate.mapping.IdGenerator;
 - import org.hibernate.mapping.Join;
 - import org.hibernate.mapping.JoinedSubclass;
 - import org.hibernate.mapping.KeyValue;
 - import org.hibernate.mapping.PersistentClass;
 - import org.hibernate.mapping.Property;
 - import org.hibernate.mapping.RootClass;
 - import org.hibernate.mapping.SimpleValue;
 - import org.hibernate.mapping.SingleTableSubclass;
 - import org.hibernate.mapping.Subclass;
 - import org.hibernate.mapping.ToOne;
 - import org.hibernate.mapping.UnionSubclass;
 - import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
 - import org.hibernate.persister.entity.SingleTableEntityPersister;
 - import org.hibernate.persister.entity.UnionSubclassEntityPersister;
 - /**
 - * JSR 175 annotation binder which reads the annotations from classes, applies the
 - * principles of the EJB3 spec and produces the Hibernate configuration-time metamodel
 - * (the classes in the {@code org.hibernate.mapping} package)
 - *
 - * @author Emmanuel Bernard
 - * @author Hardy Ferentschik
 - */
 - @SuppressWarnings("unchecked")
 - public final class AnnotationBinder {
 - /*
 - * Some design description
 - * I tried to remove any link to annotation except from the 2 first level of
 - * method call.
 - * It'll enable to:
 - * - facilitate annotation overriding
 - * - mutualize one day xml and annotation binder (probably a dream though)
 - * - split this huge class in smaller mapping oriented classes
 - *
 - * bindSomething usually create the mapping container and is accessed by one of the 2 first level method
 - * makeSomething usually create the mapping container and is accessed by bindSomething[else]
 - * fillSomething take the container into parameter and fill it.
 - */
 - private AnnotationBinder() {
 - }
 - private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
 - public static void bindDefaults(Mappings mappings) {
 - Map defaults = mappings.getReflectionManager().getDefaults();
 - {
 - List<SequenceGenerator> anns = ( List<SequenceGenerator> ) defaults.get( SequenceGenerator.class );
 - if ( anns != null ) {
 - for ( SequenceGenerator ann : anns ) {
 - IdGenerator idGen = buildIdGenerator( ann, mappings );
 - if ( idGen != null ) {
 - mappings.addDefaultGenerator( idGen );
 - }
 - }
 - }
 - }
 - {
 - List<TableGenerator> anns = ( List<TableGenerator> ) defaults.get( TableGenerator.class );
 - if ( anns != null ) {
 - for ( TableGenerator ann : anns ) {
 - IdGenerator idGen = buildIdGenerator( ann, mappings );
 - if ( idGen != null ) {
 - mappings.addDefaultGenerator( idGen );
 - }
 - }
 - }
 - }
 - {
 - List<NamedQuery> anns = ( List<NamedQuery> ) defaults.get( NamedQuery.class );
 - if ( anns != null ) {
 - for ( NamedQuery ann : anns ) {
 - QueryBinder.bindQuery( ann, mappings, true );
 - }
 - }
 - }
 - {
 - List<NamedNativeQuery> anns = ( List<NamedNativeQuery> ) defaults.get( NamedNativeQuery.class );
 - if ( anns != null ) {
 - for ( NamedNativeQuery ann : anns ) {
 - QueryBinder.bindNativeQuery( ann, mappings, true );
 - }
 - }
 - }
 - {
 - List<SqlResultSetMapping> anns = ( List<SqlResultSetMapping> ) defaults.get( SqlResultSetMapping.class );
 - if ( anns != null ) {
 - for ( SqlResultSetMapping ann : anns ) {
 - QueryBinder.bindSqlResultsetMapping( ann, mappings, true );
 - }
 - }
 - }
 - }
 - public static void bindPackage(String packageName, Mappings mappings) {
 - XPackage pckg;
 - try {
 - pckg = mappings.getReflectionManager().packageForName( packageName );
 - }
 - catch ( ClassNotFoundException cnf ) {
 - log.warn( "Package not found or wo package-info.java: {}", packageName );
 - return;
 - }
 - if ( pckg.isAnnotationPresent( SequenceGenerator.class ) ) {
 - SequenceGenerator ann = pckg.getAnnotation( SequenceGenerator.class );
 - IdGenerator idGen = buildIdGenerator( ann, mappings );
 - mappings.addGenerator( idGen );
 - log.trace( "Add sequence generator with name: {}", idGen.getName() );
 - }
 - if ( pckg.isAnnotationPresent( TableGenerator.class ) ) {
 - TableGenerator ann = pckg.getAnnotation( TableGenerator.class );
 - IdGenerator idGen = buildIdGenerator( ann, mappings );
 - mappings.addGenerator( idGen );
 - }
 - bindGenericGenerators( pckg, mappings );
 - bindQueries( pckg, mappings );
 - bindFilterDefs( pckg, mappings );
 - bindTypeDefs( pckg, mappings );
 - bindFetchProfiles( pckg, mappings );
 - BinderHelper.bindAnyMetaDefs( pckg, mappings );
 - }
 - private static void bindGenericGenerators(XAnnotatedElement annotatedElement, Mappings mappings) {
 - GenericGenerator defAnn = annotatedElement.getAnnotation( GenericGenerator.class );
 - GenericGenerators defsAnn = annotatedElement.getAnnotation( GenericGenerators.class );
 - if ( defAnn != null ) {
 - bindGenericGenerator( defAnn, mappings );
 - }
 - if ( defsAnn != null ) {
 - for ( GenericGenerator def : defsAnn.value() ) {
 - bindGenericGenerator( def, mappings );
 - }
 - }
 - }
 - private static void bindGenericGenerator(GenericGenerator def, Mappings mappings) {
 - IdGenerator idGen = buildIdGenerator( def, mappings );
 - mappings.addGenerator( idGen );
 - }
 - private static void bindQueries(XAnnotatedElement annotatedElement, Mappings mappings) {
 - {
 - SqlResultSetMapping ann = annotatedElement.getAnnotation( SqlResultSetMapping.class );
 - QueryBinder.bindSqlResultsetMapping( ann, mappings, false );
 - }
 - {
 - SqlResultSetMappings ann = annotatedElement.getAnnotation( SqlResultSetMappings.class );
 - if ( ann != null ) {
 - for ( SqlResultSetMapping current : ann.value() ) {
 - QueryBinder.bindSqlResultsetMapping( current, mappings, false );
 - }
 - }
 - }
 - {
 - NamedQuery ann = annotatedElement.getAnnotation( NamedQuery.class );
 - QueryBinder.bindQuery( ann, mappings, false );
 - }
 - {
 - org.hibernate.annotations.NamedQuery ann = annotatedElement.getAnnotation(
 - org.hibernate.annotations.NamedQuery.class
 - );
 - QueryBinder.bindQuery( ann, mappings );
 - }
 - {
 - NamedQueries ann = annotatedElement.getAnnotation( NamedQueries.class );
 - QueryBinder.bindQueries( ann, mappings, false );
 - }
 - {
 - org.hibernate.annotations.NamedQueries ann = annotatedElement.getAnnotation(
 - org.hibernate.annotations.NamedQueries.class
 - );
 - QueryBinder.bindQueries( ann, mappings );
 - }
 - {
 - NamedNativeQuery ann = annotatedElement.getAnnotation( NamedNativeQuery.class );
 - QueryBinder.bindNativeQuery( ann, mappings, false );
 - }
 - {
 - org.hibernate.annotations.NamedNativeQuery ann = annotatedElement.getAnnotation(
 - org.hibernate.annotations.NamedNativeQuery.class
 - );
 - QueryBinder.bindNativeQuery( ann, mappings );
 - }
 - {
 - NamedNativeQueries ann = annotatedElement.getAnnotation( NamedNativeQueries.class );
 - QueryBinder.bindNativeQueries( ann, mappings, false );
 - }
 - {
 - org.hibernate.annotations.NamedNativeQueries ann = annotatedElement.getAnnotation(
 - org.hibernate.annotations.NamedNativeQueries.class
 - );
 - QueryBinder.bindNativeQueries( ann, mappings );
 - }
 - }
 - private static IdGenerator buildIdGenerator(java.lang.annotation.Annotation ann, Mappings mappings) {
 - IdGenerator idGen = new IdGenerator();
 - if ( mappings.getSchemaName() != null ) {
 - idGen.addParam( PersistentIdentifierGenerator.SCHEMA, mappings.getSchemaName() );
 - }
 - if ( mappings.getCatalogName() != null ) {
 - idGen.addParam( PersistentIdentifierGenerator.CATALOG, mappings.getCatalogName() );
 - }
 - final boolean useNewGeneratorMappings = mappings.useNewGeneratorMappings();
 - if ( ann == null ) {
 - idGen = null;
 - }
 - else if ( ann instanceof TableGenerator ) {
 - TableGenerator tabGen = ( TableGenerator ) ann;
 - idGen.setName( tabGen.name() );
 - if ( useNewGeneratorMappings ) {
 - idGen.setIdentifierGeneratorStrategy( org.hibernate.id.enhanced.TableGenerator.class.getName() );
 - idGen.addParam( org.hibernate.id.enhanced.TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" );
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.catalog() ) ) {
 - idGen.addParam( org.hibernate.id.enhanced.TableGenerator.CATALOG, tabGen.catalog() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.schema() ) ) {
 - idGen.addParam( org.hibernate.id.enhanced.TableGenerator.SCHEMA, tabGen.schema() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.table() ) ) {
 - idGen.addParam( org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM, tabGen.table() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.pkColumnName() ) ) {
 - idGen.addParam(
 - org.hibernate.id.enhanced.TableGenerator.SEGMENT_COLUMN_PARAM, tabGen.pkColumnName()
 - );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.pkColumnValue() ) ) {
 - idGen.addParam(
 - org.hibernate.id.enhanced.TableGenerator.SEGMENT_VALUE_PARAM, tabGen.pkColumnValue()
 - );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.valueColumnName() ) ) {
 - idGen.addParam(
 - org.hibernate.id.enhanced.TableGenerator.VALUE_COLUMN_PARAM, tabGen.valueColumnName()
 - );
 - }
 - idGen.addParam(
 - org.hibernate.id.enhanced.TableGenerator.INCREMENT_PARAM,
 - String.valueOf( tabGen.allocationSize() )
 - );
 - // See comment on HHH-4884 wrt initialValue. Basically initialValue is really the stated value + 1
 - idGen.addParam(
 - org.hibernate.id.enhanced.TableGenerator.INITIAL_PARAM,
 - String.valueOf( tabGen.initialValue() + 1 )
 - );
 - if ( tabGen.uniqueConstraints() != null && tabGen.uniqueConstraints().length > 0 ) {
 - log.warn( "Ignoring unique constraints specified on table generator [{}]", tabGen.name() );
 - }
 - }
 - else {
 - idGen.setIdentifierGeneratorStrategy( MultipleHiLoPerTableGenerator.class.getName() );
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.table() ) ) {
 - idGen.addParam( MultipleHiLoPerTableGenerator.ID_TABLE, tabGen.table() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.catalog() ) ) {
 - idGen.addParam( MultipleHiLoPerTableGenerator.CATALOG, tabGen.catalog() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.schema() ) ) {
 - idGen.addParam( MultipleHiLoPerTableGenerator.SCHEMA, tabGen.schema() );
 - }
 - //FIXME implement uniqueconstrains
 - if ( tabGen.uniqueConstraints() != null && tabGen.uniqueConstraints().length > 0 ) {
 - log.warn( "Ignoring unique constraints specified on table generator [{}]", tabGen.name() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.pkColumnName() ) ) {
 - idGen.addParam( MultipleHiLoPerTableGenerator.PK_COLUMN_NAME, tabGen.pkColumnName() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.valueColumnName() ) ) {
 - idGen.addParam( MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME, tabGen.valueColumnName() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tabGen.pkColumnValue() ) ) {
 - idGen.addParam( MultipleHiLoPerTableGenerator.PK_VALUE_NAME, tabGen.pkColumnValue() );
 - }
 - idGen.addParam( TableHiLoGenerator.MAX_LO, String.valueOf( tabGen.allocationSize() - 1 ) );
 - }
 - log.trace( "Add table generator with name: {}", idGen.getName() );
 - }
 - else if ( ann instanceof SequenceGenerator ) {
 - SequenceGenerator seqGen = ( SequenceGenerator ) ann;
 - idGen.setName( seqGen.name() );
 - if ( useNewGeneratorMappings ) {
 - idGen.setIdentifierGeneratorStrategy( SequenceStyleGenerator.class.getName() );
 - if ( !BinderHelper.isEmptyAnnotationValue( seqGen.catalog() ) ) {
 - idGen.addParam( SequenceStyleGenerator.CATALOG, seqGen.catalog() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( seqGen.schema() ) ) {
 - idGen.addParam( SequenceStyleGenerator.SCHEMA, seqGen.schema() );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( seqGen.sequenceName() ) ) {
 - idGen.addParam( SequenceStyleGenerator.SEQUENCE_PARAM, seqGen.sequenceName() );
 - }
 - idGen.addParam( SequenceStyleGenerator.INCREMENT_PARAM, String.valueOf( seqGen.allocationSize() ) );
 - idGen.addParam( SequenceStyleGenerator.INITIAL_PARAM, String.valueOf( seqGen.initialValue() ) );
 - }
 - else {
 - idGen.setIdentifierGeneratorStrategy( "seqhilo" );
 - if ( !BinderHelper.isEmptyAnnotationValue( seqGen.sequenceName() ) ) {
 - idGen.addParam( org.hibernate.id.SequenceGenerator.SEQUENCE, seqGen.sequenceName() );
 - }
 - //FIXME: work on initialValue() through SequenceGenerator.PARAMETERS
 - // steve : or just use o.h.id.enhanced.SequenceStyleGenerator
 - if ( seqGen.initialValue() != 1 ) {
 - log.warn(
 - "Hibernate does not support SequenceGenerator.initialValue() unless '{}' set",
 - Configuration.USE_NEW_ID_GENERATOR_MAPPINGS
 - );
 - }
 - idGen.addParam( SequenceHiLoGenerator.MAX_LO, String.valueOf( seqGen.allocationSize() - 1 ) );
 - log.trace( "Add sequence generator with name: {}", idGen.getName() );
 - }
 - }
 - else if ( ann instanceof GenericGenerator ) {
 - GenericGenerator genGen = ( GenericGenerator ) ann;
 - idGen.setName( genGen.name() );
 - idGen.setIdentifierGeneratorStrategy( genGen.strategy() );
 - Parameter[] params = genGen.parameters();
 - for ( Parameter parameter : params ) {
 - idGen.addParam( parameter.name(), parameter.value() );
 - }
 - log.trace( "Add generic generator with name: {}", idGen.getName() );
 - }
 - else {
 - throw new AssertionFailure( "Unknown Generator annotation: " + ann );
 - }
 - return idGen;
 - }
 - /**
 - * Bind a class having JSR175 annotations. Subclasses <b>have to</b> be bound after its parent class.
 - *
 - * @param clazzToProcess entity to bind as {@code XClass} instance
 - * @param inheritanceStatePerClass Meta data about the inheritance relationships for all mapped classes
 - * @param mappings Mapping meta data
 - *
 - * @throws MappingException in case there is an configuration error
 - */
 - public static void bindClass(
 - XClass clazzToProcess,
 - Map<XClass, InheritanceState> inheritanceStatePerClass,
 - Mappings mappings) throws MappingException {
 - //@Entity and @MappedSuperclass on the same class leads to a NPE down the road
 - if ( clazzToProcess.isAnnotationPresent( Entity.class )
 - && clazzToProcess.isAnnotationPresent( MappedSuperclass.class ) ) {
 - throw new AnnotationException( "An entity cannot be annotated with both @Entity and @MappedSuperclass: "
 - + clazzToProcess.getName() );
 - }
 - //TODO: be more strict with secondarytable allowance (not for ids, not for secondary table join columns etc)
 - InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess );
 - AnnotatedClassType classType = mappings.getClassType( clazzToProcess );
 - //Queries declared in MappedSuperclass should be usable in Subclasses
 - if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) ) {
 - bindQueries( clazzToProcess, mappings );
 - bindTypeDefs( clazzToProcess, mappings );
 - bindFilterDefs( clazzToProcess, mappings );
 - }
 - if ( !isEntityClassType( clazzToProcess, classType ) ) {
 - return;
 - }
 - log.info( "Binding entity from annotated class: {}", clazzToProcess.getName() );
 - PersistentClass superEntity = getSuperEntity(
 - clazzToProcess, inheritanceStatePerClass, mappings, inheritanceState
 - );
 - PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity );
 - Entity entityAnn = clazzToProcess.getAnnotation( Entity.class );
 - org.hibernate.annotations.Entity hibEntityAnn = clazzToProcess.getAnnotation(
 - org.hibernate.annotations.Entity.class
 - );
 - EntityBinder entityBinder = new EntityBinder(
 - entityAnn, hibEntityAnn, clazzToProcess, persistentClass, mappings
 - );
 - entityBinder.setInheritanceState( inheritanceState );
 - bindQueries( clazzToProcess, mappings );
 - bindFilterDefs( clazzToProcess, mappings );
 - bindTypeDefs( clazzToProcess, mappings );
 - bindFetchProfiles( clazzToProcess, mappings );
 - BinderHelper.bindAnyMetaDefs( clazzToProcess, mappings );
 - String schema = "";
 - String table = ""; //might be no @Table annotation on the annotated class
 - String catalog = "";
 - List<UniqueConstraintHolder> uniqueConstraints = new ArrayList<UniqueConstraintHolder>();
 - if ( clazzToProcess.isAnnotationPresent( javax.persistence.Table.class ) ) {
 - javax.persistence.Table tabAnn = clazzToProcess.getAnnotation( javax.persistence.Table.class );
 - table = tabAnn.name();
 - schema = tabAnn.schema();
 - catalog = tabAnn.catalog();
 - uniqueConstraints = TableBinder.buildUniqueConstraintHolders( tabAnn.uniqueConstraints() );
 - }
 - Ejb3JoinColumn[] inheritanceJoinedColumns = makeInheritanceJoinColumns(
 - clazzToProcess, mappings, inheritanceState, superEntity
 - );
 - Ejb3DiscriminatorColumn discriminatorColumn = null;
 - if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
 - discriminatorColumn = processDiscriminatorProperties(
 - clazzToProcess, mappings, inheritanceState, entityBinder
 - );
 - }
 - entityBinder.setProxy( clazzToProcess.getAnnotation( Proxy.class ) );
 - entityBinder.setBatchSize( clazzToProcess.getAnnotation( BatchSize.class ) );
 - entityBinder.setWhere( clazzToProcess.getAnnotation( Where.class ) );
 - entityBinder.setCache( determineCacheSettings( clazzToProcess, mappings ) );
 - //Filters are not allowed on subclasses
 - if ( !inheritanceState.hasParents() ) {
 - bindFilters( clazzToProcess, entityBinder, mappings );
 - }
 - entityBinder.bindEntity();
 - if ( inheritanceState.hasTable() ) {
 - Check checkAnn = clazzToProcess.getAnnotation( Check.class );
 - String constraints = checkAnn == null ?
 - null :
 - checkAnn.constraints();
 - entityBinder.bindTable(
 - schema, catalog, table, uniqueConstraints,
 - constraints, inheritanceState.hasDenormalizedTable() ?
 - superEntity.getTable() :
 - null
 - );
 - }
 - else {
 - if ( clazzToProcess.isAnnotationPresent( Table.class ) ) {
 - log.warn(
 - "Illegal use of @Table in a subclass of a SINGLE_TABLE hierarchy: " + clazzToProcess
 - .getName()
 - );
 - }
 - }
 - PropertyHolder propertyHolder = PropertyHolderBuilder.buildPropertyHolder(
 - clazzToProcess,
 - persistentClass,
 - entityBinder, mappings, inheritanceStatePerClass
 - );
 - javax.persistence.SecondaryTable secTabAnn = clazzToProcess.getAnnotation(
 - javax.persistence.SecondaryTable.class
 - );
 - javax.persistence.SecondaryTables secTabsAnn = clazzToProcess.getAnnotation(
 - javax.persistence.SecondaryTables.class
 - );
 - entityBinder.firstLevelSecondaryTablesBinding( secTabAnn, secTabsAnn );
 - OnDelete onDeleteAnn = clazzToProcess.getAnnotation( OnDelete.class );
 - boolean onDeleteAppropriate = false;
 - if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) && inheritanceState.hasParents() ) {
 - onDeleteAppropriate = true;
 - final JoinedSubclass jsc = ( JoinedSubclass ) persistentClass;
 - if ( persistentClass.getEntityPersisterClass() == null ) {
 - persistentClass.getRootClass().setEntityPersisterClass( JoinedSubclassEntityPersister.class );
 - }
 - SimpleValue key = new DependantValue( mappings, jsc.getTable(), jsc.getIdentifier() );
 - jsc.setKey( key );
 - ForeignKey fk = clazzToProcess.getAnnotation( ForeignKey.class );
 - if ( fk != null && !BinderHelper.isEmptyAnnotationValue( fk.name() ) ) {
 - key.setForeignKeyName( fk.name() );
 - }
 - if ( onDeleteAnn != null ) {
 - key.setCascadeDeleteEnabled( OnDeleteAction.CASCADE.equals( onDeleteAnn.action() ) );
 - }
 - else {
 - key.setCascadeDeleteEnabled( false );
 - }
 - //we are never in a second pass at that stage, so queue it
 - SecondPass sp = new JoinedSubclassFkSecondPass( jsc, inheritanceJoinedColumns, key, mappings );
 - mappings.addSecondPass( sp );
 - mappings.addSecondPass( new CreateKeySecondPass( jsc ) );
 - }
 - else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
 - if ( inheritanceState.hasParents() ) {
 - if ( persistentClass.getEntityPersisterClass() == null ) {
 - persistentClass.getRootClass().setEntityPersisterClass( SingleTableEntityPersister.class );
 - }
 - }
 - else {
 - if ( inheritanceState.hasSiblings() || !discriminatorColumn.isImplicit() ) {
 - //need a discriminator column
 - bindDiscriminatorToPersistentClass(
 - ( RootClass ) persistentClass,
 - discriminatorColumn,
 - entityBinder.getSecondaryTables(),
 - propertyHolder,
 - mappings
 - );
 - entityBinder.bindDiscriminatorValue();//bind it again since the type might have changed
 - }
 - }
 - }
 - else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
 - if ( inheritanceState.hasParents() ) {
 - if ( persistentClass.getEntityPersisterClass() == null ) {
 - persistentClass.getRootClass().setEntityPersisterClass( UnionSubclassEntityPersister.class );
 - }
 - }
 - }
 - if ( onDeleteAnn != null && !onDeleteAppropriate ) {
 - log.warn(
 - "Inapropriate use of @OnDelete on entity, annotation ignored: {}", propertyHolder.getEntityName()
 - );
 - }
 - // try to find class level generators
 - HashMap<String, IdGenerator> classGenerators = buildLocalGenerators( clazzToProcess, mappings );
 - // check properties
 - final InheritanceState.ElementsToProcess elementsToProcess = inheritanceState.getElementsToProcess();
 - inheritanceState.postProcess( persistentClass, entityBinder );
 - final boolean subclassAndSingleTableStrategy = inheritanceState.getType() == InheritanceType.SINGLE_TABLE
 - && inheritanceState.hasParents();
 - Set<String> idPropertiesIfIdClass = new HashSet<String>();
 - boolean isIdClass = mapAsIdClass(
 - inheritanceStatePerClass,
 - inheritanceState,
 - persistentClass,
 - entityBinder,
 - propertyHolder,
 - elementsToProcess,
 - idPropertiesIfIdClass,
 - mappings
 - );
 - if ( !isIdClass ) {
 - entityBinder.setWrapIdsInEmbeddedComponents( elementsToProcess.getIdPropertyCount() > 1 );
 - }
 - processIdPropertiesIfNotAlready(
 - inheritanceStatePerClass,
 - mappings,
 - persistentClass,
 - entityBinder,
 - propertyHolder,
 - classGenerators,
 - elementsToProcess,
 - subclassAndSingleTableStrategy,
 - idPropertiesIfIdClass
 - );
 - 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, clazzToProcess ) );
 - //add process complementary Table definition (index & all)
 - entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Table.class ) );
 - entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Tables.class ) );
 - CommentBinder.bindTableComment(clazzToProcess, persistentClass);//绑定表名注释
 - }
 - // parse everything discriminator column relevant in case of single table inheritance
 - private static Ejb3DiscriminatorColumn processDiscriminatorProperties(XClass clazzToProcess, Mappings mappings, InheritanceState inheritanceState, EntityBinder entityBinder) {
 - Ejb3DiscriminatorColumn discriminatorColumn = null;
 - javax.persistence.DiscriminatorColumn discAnn = clazzToProcess.getAnnotation(
 - javax.persistence.DiscriminatorColumn.class
 - );
 - DiscriminatorType discriminatorType = discAnn != null ?
 - discAnn.discriminatorType() :
 - DiscriminatorType.STRING;
 - org.hibernate.annotations.DiscriminatorFormula discFormulaAnn = clazzToProcess.getAnnotation(
 - org.hibernate.annotations.DiscriminatorFormula.class
 - );
 - if ( !inheritanceState.hasParents() ) {
 - discriminatorColumn = Ejb3DiscriminatorColumn.buildDiscriminatorColumn(
 - discriminatorType, discAnn, discFormulaAnn, mappings
 - );
 - }
 - if ( discAnn != null && inheritanceState.hasParents() ) {
 - log.warn(
 - "Discriminator column has to be defined in the root entity, it will be ignored in subclass: {}",
 - clazzToProcess.getName()
 - );
 - }
 - String discrimValue = clazzToProcess.isAnnotationPresent( DiscriminatorValue.class ) ?
 - clazzToProcess.getAnnotation( DiscriminatorValue.class ).value() :
 - null;
 - entityBinder.setDiscriminatorValue( discrimValue );
 - if ( clazzToProcess.isAnnotationPresent( ForceDiscriminator.class ) ) {
 - log.warn( "@ForceDiscriminator is deprecated use @DiscriminatorOptions instead." );
 - entityBinder.setForceDiscriminator( true );
 - }
 - DiscriminatorOptions discriminatorOptions = clazzToProcess.getAnnotation( DiscriminatorOptions.class );
 - if ( discriminatorOptions != null) {
 - entityBinder.setForceDiscriminator( discriminatorOptions.force() );
 - entityBinder.setInsertableDiscriminator( discriminatorOptions.insert() );
 - }
 - return discriminatorColumn;
 - }
 - private static void processIdPropertiesIfNotAlready(
 - Map<XClass, InheritanceState> inheritanceStatePerClass,
 - Mappings mappings,
 - PersistentClass persistentClass,
 - EntityBinder entityBinder,
 - PropertyHolder propertyHolder,
 - HashMap<String, IdGenerator> classGenerators,
 - InheritanceState.ElementsToProcess elementsToProcess,
 - boolean subclassAndSingleTableStrategy,
 - Set<String> idPropertiesIfIdClass) {
 - Set<String> missingIdProperties = new HashSet<String>( idPropertiesIfIdClass );
 - for ( PropertyData propertyAnnotatedElement : elementsToProcess.getElements() ) {
 - String propertyName = propertyAnnotatedElement.getPropertyName();
 - if ( !idPropertiesIfIdClass.contains( propertyName ) ) {
 - processElementAnnotations(
 - propertyHolder,
 - subclassAndSingleTableStrategy ?
 - Nullability.FORCED_NULL :
 - Nullability.NO_CONSTRAINT,
 - propertyAnnotatedElement, classGenerators, entityBinder,
 - false, false, false, mappings, inheritanceStatePerClass
 - );
 - }
 - 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()
 - );
 - }
 - }
 - private static boolean mapAsIdClass(
 - Map<XClass, InheritanceState> inheritanceStatePerClass,
 - InheritanceState inheritanceState,
 - PersistentClass persistentClass,
 - EntityBinder entityBinder,
 - PropertyHolder propertyHolder,
 - InheritanceState.ElementsToProcess elementsToProcess,
 - Set<String> idPropertiesIfIdClass,
 - Mappings mappings) {
 - /*
 - * We are looking for @IdClass
 - * In general we map the id class as identifier using the mapping metadata of the main entity's properties
 - * and we create an identifier mapper containing the id properties of the main entity
 - *
 - * In JPA 2, there is a shortcut if the id class is the Pk of the associated class pointed to by the id
 - * it ought to be treated as an embedded and not a real IdClass (at least in the Hibernate's internal way
 - */
 - XClass classWithIdClass = inheritanceState.getClassWithIdClass( false );
 - if ( classWithIdClass != null ) {
 - IdClass idClass = classWithIdClass.getAnnotation( IdClass.class );
 - XClass compositeClass = mappings.getReflectionManager().toXClass( idClass.value() );
 - PropertyData inferredData = new PropertyPreloadedData(
 - entityBinder.getPropertyAccessType(), "id", compositeClass
 - );
 - PropertyData baseInferredData = new PropertyPreloadedData(
 - entityBinder.getPropertyAccessType(), "id", classWithIdClass
 - );
 - AccessType propertyAccessor = entityBinder.getPropertyAccessor( compositeClass );
 - //In JPA 2, there is a shortcut if the IdClass is the Pk of the associated class pointed to by the id
 - //it ought to be treated as an embedded and not a real IdClass (at least in the Hibernate's internal way
 - final boolean isFakeIdClass = isIdClassPkOfTheAssociatedEntity(
 - elementsToProcess,
 - compositeClass,
 - inferredData,
 - baseInferredData,
 - propertyAccessor,
 - inheritanceStatePerClass,
 - mappings
 - );
 - if ( isFakeIdClass ) {
 - return false;
 - }
 - boolean isComponent = true;
 - String generatorType = "assigned";
 - String generator = BinderHelper.ANNOTATION_STRING_DEFAULT;
 - boolean ignoreIdAnnotations = entityBinder.isIgnoreIdAnnotations();
 - entityBinder.setIgnoreIdAnnotations( true );
 - propertyHolder.setInIdClass( true );
 - bindIdClass(
 - generatorType,
 - generator,
 - inferredData,
 - baseInferredData,
 - null,
 - propertyHolder,
 - isComponent,
 - propertyAccessor,
 - entityBinder,
 - true,
 - false,
 - mappings,
 - inheritanceStatePerClass
 - );
 - propertyHolder.setInIdClass( null );
 - inferredData = new PropertyPreloadedData(
 - propertyAccessor, "_identifierMapper", compositeClass
 - );
 - Component mapper = fillComponent(
 - propertyHolder,
 - inferredData,
 - baseInferredData,
 - propertyAccessor,
 - false,
 - entityBinder,
 - true,
 - true,
 - false,
 - mappings,
 - inheritanceStatePerClass
 - );
 - entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations );
 - persistentClass.setIdentifierMapper( mapper );
 - //If id definition is on a mapped superclass, update the mapping
 - final org.hibernate.mapping.MappedSuperclass superclass =
 - BinderHelper.getMappedSuperclassOrNull(
 - inferredData.getDeclaringClass(),
 - inheritanceStatePerClass,
 - mappings
 - );
 - if ( superclass != null ) {
 - superclass.setDeclaredIdentifierMapper( mapper );
 - }
 - else {
 - //we are for sure on the entity
 - persistentClass.setDeclaredIdentifierMapper( 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() ) {
 - idPropertiesIfIdClass.add( ( ( Property ) properties.next() ).getName() );
 - }
 - return true;
 - }
 - else {
 - return false;
 - }
 - }
 - private static boolean isIdClassPkOfTheAssociatedEntity(
 - InheritanceState.ElementsToProcess elementsToProcess,
 - XClass compositeClass,
 - PropertyData inferredData,
 - PropertyData baseInferredData,
 - AccessType propertyAccessor,
 - Map<XClass, InheritanceState> inheritanceStatePerClass,
 - Mappings mappings) {
 - if ( elementsToProcess.getIdPropertyCount() == 1 ) {
 - final PropertyData idPropertyOnBaseClass = getUniqueIdPropertyFromBaseClass(
 - inferredData, baseInferredData, propertyAccessor, mappings
 - );
 - final InheritanceState state = inheritanceStatePerClass.get( idPropertyOnBaseClass.getClassOrElement() );
 - if ( state == null ) {
 - return false; //while it is likely a user error, let's consider it is something that might happen
 - }
 - final XClass associatedClassWithIdClass = state.getClassWithIdClass( true );
 - if ( associatedClassWithIdClass == null ) {
 - //we cannot know for sure here unless we try and find the @EmbeddedId
 - //Let's not do this thorough checking but do some extra validation
 - final XProperty property = idPropertyOnBaseClass.getProperty();
 - return property.isAnnotationPresent( ManyToOne.class )
 - || property.isAnnotationPresent( OneToOne.class );
 - }
 - else {
 - final XClass idClass = mappings.getReflectionManager().toXClass(
 - associatedClassWithIdClass.getAnnotation( IdClass.class ).value()
 - );
 - return idClass.equals( compositeClass );
 - }
 - }
 - else {
 - return false;
 - }
 - }
 - private static Cache determineCacheSettings(XClass clazzToProcess, Mappings mappings) {
 - Cache cacheAnn = clazzToProcess.getAnnotation( Cache.class );
 - if ( cacheAnn != null ) {
 - return cacheAnn;
 - }
 - Cacheable cacheableAnn = clazzToProcess.getAnnotation( Cacheable.class );
 - SharedCacheMode mode = determineSharedCacheMode( mappings );
 - switch ( mode ) {
 - case ALL: {
 - cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings );
 - break;
 - }
 - case ENABLE_SELECTIVE: {
 - if ( cacheableAnn != null && cacheableAnn.value() ) {
 - cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings );
 - }
 - break;
 - }
 - case DISABLE_SELECTIVE: {
 - if ( cacheableAnn == null || cacheableAnn.value() ) {
 - cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings );
 - }
 - break;
 - }
 - default: {
 - // treat both NONE and UNSPECIFIED the same
 - break;
 - }
 - }
 - return cacheAnn;
 - }
 - private static SharedCacheMode determineSharedCacheMode(Mappings mappings) {
 - SharedCacheMode mode;
 - final Object value = mappings.getConfigurationProperties().get( "javax.persistence.sharedCache.mode" );
 - if ( value == null ) {
 - log.debug( "no value specified for 'javax.persistence.sharedCache.mode'; using UNSPECIFIED" );
 - mode = SharedCacheMode.UNSPECIFIED;
 - }
 - else {
 - if ( SharedCacheMode.class.isInstance( value ) ) {
 - mode = ( SharedCacheMode ) value;
 - }
 - else {
 - try {
 - mode = SharedCacheMode.valueOf( value.toString() );
 - }
 - catch ( Exception e ) {
 - log.debug(
 - "Unable to resolve given mode name [" + value.toString()
 - + "]; using UNSPECIFIED : " + e.toString()
 - );
 - mode = SharedCacheMode.UNSPECIFIED;
 - }
 - }
 - }
 - return mode;
 - }
 - private static Cache buildCacheMock(String region, Mappings mappings) {
 - return new LocalCacheAnnotationImpl( region, determineCacheConcurrencyStrategy( mappings ) );
 - }
 - private static CacheConcurrencyStrategy DEFAULT_CACHE_CONCURRENCY_STRATEGY;
 - static void prepareDefaultCacheConcurrencyStrategy(Properties properties) {
 - if ( DEFAULT_CACHE_CONCURRENCY_STRATEGY != null ) {
 - log.trace( "Default cache concurrency strategy already defined" );
 - return;
 - }
 - if ( !properties.containsKey( Configuration.DEFAULT_CACHE_CONCURRENCY_STRATEGY ) ) {
 - log.trace( "Given properties did not contain any default cache concurrency strategy setting" );
 - return;
 - }
 - final String strategyName = properties.getProperty( Configuration.DEFAULT_CACHE_CONCURRENCY_STRATEGY );
 - log.trace( "Discovered default cache concurrency strategy via config [" + strategyName + "]" );
 - CacheConcurrencyStrategy strategy = CacheConcurrencyStrategy.parse( strategyName );
 - if ( strategy == null ) {
 - log.trace( "Discovered default cache concurrency strategy specified nothing" );
 - return;
 - }
 - log.debug( "Setting default cache concurrency strategy via config [" + strategy.name() + "]" );
 - DEFAULT_CACHE_CONCURRENCY_STRATEGY = strategy;
 - }
 - private static CacheConcurrencyStrategy determineCacheConcurrencyStrategy(Mappings mappings) {
 - if ( DEFAULT_CACHE_CONCURRENCY_STRATEGY == null ) {
 - final RegionFactory cacheRegionFactory = SettingsFactory.createRegionFactory(
 - mappings.getConfigurationProperties(), true
 - );
 - DEFAULT_CACHE_CONCURRENCY_STRATEGY = CacheConcurrencyStrategy.fromAccessType( cacheRegionFactory.getDefaultAccessType() );
 - }
 - return DEFAULT_CACHE_CONCURRENCY_STRATEGY;
 - }
 - @SuppressWarnings({ "ClassExplicitlyAnnotation" })
 - private static class LocalCacheAnnotationImpl implements Cache {
 - private final String region;
 - private final CacheConcurrencyStrategy usage;
 - private LocalCacheAnnotationImpl(String region, CacheConcurrencyStrategy usage) {
 - this.region = region;
 - this.usage = usage;
 - }
 - public CacheConcurrencyStrategy usage() {
 - return usage;
 - }
 - public String region() {
 - return region;
 - }
 - public String include() {
 - return "all";
 - }
 - public Class<? extends Annotation> annotationType() {
 - return Cache.class;
 - }
 - }
 - private static PersistentClass makePersistentClass(InheritanceState inheritanceState, PersistentClass superEntity) {
 - //we now know what kind of persistent entity it is
 - PersistentClass persistentClass;
 - //create persistent class
 - if ( !inheritanceState.hasParents() ) {
 - persistentClass = new RootClass();
 - }
 - else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
 - persistentClass = new SingleTableSubclass( superEntity );
 - }
 - else if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) ) {
 - persistentClass = new JoinedSubclass( superEntity );
 - }
 - else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
 - persistentClass = new UnionSubclass( superEntity );
 - }
 - else {
 - throw new AssertionFailure( "Unknown inheritance type: " + inheritanceState.getType() );
 - }
 - return persistentClass;
 - }
 - private static Ejb3JoinColumn[] makeInheritanceJoinColumns(
 - XClass clazzToProcess,
 - Mappings mappings,
 - InheritanceState inheritanceState,
 - PersistentClass superEntity) {
 - Ejb3JoinColumn[] inheritanceJoinedColumns = null;
 - final boolean hasJoinedColumns = inheritanceState.hasParents()
 - && InheritanceType.JOINED.equals( inheritanceState.getType() );
 - if ( hasJoinedColumns ) {
 - //@Inheritance(JOINED) subclass need to link back to the super entity
 - PrimaryKeyJoinColumns jcsAnn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumns.class );
 - boolean explicitInheritanceJoinedColumns = jcsAnn != null && jcsAnn.value().length != 0;
 - if ( explicitInheritanceJoinedColumns ) {
 - int nbrOfInhJoinedColumns = jcsAnn.value().length;
 - PrimaryKeyJoinColumn jcAnn;
 - inheritanceJoinedColumns = new Ejb3JoinColumn[nbrOfInhJoinedColumns];
 - for ( int colIndex = 0; colIndex < nbrOfInhJoinedColumns; colIndex++ ) {
 - jcAnn = jcsAnn.value()[colIndex];
 - inheritanceJoinedColumns[colIndex] = Ejb3JoinColumn.buildJoinColumn(
 - jcAnn, null, superEntity.getIdentifier(),
 - ( Map<String, Join> ) null, ( PropertyHolder ) null, mappings
 - );
 - }
 - }
 - else {
 - PrimaryKeyJoinColumn jcAnn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class );
 - inheritanceJoinedColumns = new Ejb3JoinColumn[1];
 - inheritanceJoinedColumns[0] = Ejb3JoinColumn.buildJoinColumn(
 - jcAnn, null, superEntity.getIdentifier(),
 - ( Map<String, Join> ) null, ( PropertyHolder ) null, mappings
 - );
 - }
 - log.trace( "Subclass joined column(s) created" );
 - }
 - else {
 - if ( clazzToProcess.isAnnotationPresent( PrimaryKeyJoinColumns.class )
 - || clazzToProcess.isAnnotationPresent( PrimaryKeyJoinColumn.class ) ) {
 - log.warn( "Root entity should not hold an PrimaryKeyJoinColum(s), will be ignored" );
 - }
 - }
 - return inheritanceJoinedColumns;
 - }
 - private static PersistentClass getSuperEntity(XClass clazzToProcess, Map<XClass, InheritanceState> inheritanceStatePerClass, Mappings mappings, InheritanceState inheritanceState) {
 - InheritanceState superEntityState = InheritanceState.getInheritanceStateOfSuperEntity(
 - clazzToProcess, inheritanceStatePerClass
 - );
 - PersistentClass superEntity = superEntityState != null ?
 - mappings.getClass(
 - superEntityState.getClazz().getName()
 - ) :
 - null;
 - if ( superEntity == null ) {
 - //check if superclass is not a potential persistent class
 - if ( inheritanceState.hasParents() ) {
 - throw new AssertionFailure(
 - "Subclass has to be binded after it's mother class: "
 - + superEntityState.getClazz().getName()
 - );
 - }
 - }
 - return superEntity;
 - }
 - private static boolean isEntityClassType(XClass clazzToProcess, AnnotatedClassType classType) {
 - if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) //will be processed by their subentities
 - || AnnotatedClassType.NONE.equals( classType ) //to be ignored
 - || AnnotatedClassType.EMBEDDABLE.equals( classType ) //allow embeddable element declaration
 - ) {
 - if ( AnnotatedClassType.NONE.equals( classType )
 - && clazzToProcess.isAnnotationPresent( org.hibernate.annotations.Entity.class ) ) {
 - log.warn(
 - "Class annotated @org.hibernate.annotations.Entity but not javax.persistence.Entity "
 - + "(most likely a user error): {}", clazzToProcess.getName()
 - );
 - }
 - return false;
 - }
 - if ( !classType.equals( AnnotatedClassType.ENTITY ) ) {
 - throw new AnnotationException(
 - "Annotated class should have a @javax.persistence.Entity, @javax.persistence.Embeddable or @javax.persistence.EmbeddedSuperclass annotation: " + clazzToProcess
 - .getName()
 - );
 - }
 - return true;
 - }
 - /*
 - * Process the filters defined on the given class, as well as all filters defined
 - * on the MappedSuperclass(s) in the inheritance hierarchy
 - */
 - private static void bindFilters(XClass annotatedClass, EntityBinder entityBinder,
 - Mappings mappings) {
 - bindFilters( annotatedClass, entityBinder );
 - XClass classToProcess = annotatedClass.getSuperclass();
 - while ( classToProcess != null ) {
 - AnnotatedClassType classType = mappings.getClassType( classToProcess );
 - if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) ) {
 - bindFilters( classToProcess, entityBinder );
 - }
 - classToProcess = classToProcess.getSuperclass();
 - }
 - }
 - private static void bindFilters(XAnnotatedElement annotatedElement, EntityBinder entityBinder) {
 - Filters filtersAnn = annotatedElement.getAnnotation( Filters.class );
 - if ( filtersAnn != null ) {
 - for ( Filter filter : filtersAnn.value() ) {
 - entityBinder.addFilter( filter.name(), filter.condition() );
 - }
 - }
 - Filter filterAnn = annotatedElement.getAnnotation( Filter.class );
 - if ( filterAnn != null ) {
 - entityBinder.addFilter( filterAnn.name(), filterAnn.condition() );
 - }
 - }
 - private static void bindFilterDefs(XAnnotatedElement annotatedElement, Mappings 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, Mappings mappings) {
 - Map<String, org.hibernate.type.Type> params = new HashMap<String, org.hibernate.type.Type>();
 - for ( ParamDef param : defAnn.parameters() ) {
 - params.put( param.name(), mappings.getTypeResolver().heuristicType( param.type() ) );
 - }
 - FilterDefinition def = new FilterDefinition( defAnn.name(), defAnn.defaultCondition(), params );
 - log.info( "Binding filter definition: {}", def.getFilterName() );
 - mappings.addFilterDefinition( def );
 - }
 - private static void bindTypeDefs(XAnnotatedElement annotatedElement, Mappings 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 bindFetchProfiles(XAnnotatedElement annotatedElement, Mappings mappings) {
 - FetchProfile fetchProfileAnnotation = annotatedElement.getAnnotation( FetchProfile.class );
 - FetchProfiles fetchProfileAnnotations = annotatedElement.getAnnotation( FetchProfiles.class );
 - if ( fetchProfileAnnotation != null ) {
 - bindFetchProfile( fetchProfileAnnotation, mappings );
 - }
 - if ( fetchProfileAnnotations != null ) {
 - for ( FetchProfile profile : fetchProfileAnnotations.value() ) {
 - bindFetchProfile( profile, mappings );
 - }
 - }
 - }
 - private static void bindFetchProfile(FetchProfile fetchProfileAnnotation, Mappings mappings) {
 - for ( FetchProfile.FetchOverride fetch : fetchProfileAnnotation.fetchOverrides() ) {
 - org.hibernate.annotations.FetchMode mode = fetch.mode();
 - if ( !mode.equals( org.hibernate.annotations.FetchMode.JOIN ) ) {
 - throw new MappingException( "Only FetchMode.JOIN is currently supported" );
 - }
 - SecondPass sp = new VerifyFetchProfileReferenceSecondPass( fetchProfileAnnotation.name(), fetch, mappings );
 - mappings.addSecondPass( sp );
 - }
 - }
 - private static void bindTypeDef(TypeDef defAnn, Mappings mappings) {
 - Properties params = new Properties();
 - for ( Parameter param : defAnn.parameters() ) {
 - params.setProperty( param.name(), param.value() );
 - }
 - if ( BinderHelper.isEmptyAnnotationValue( defAnn.name() ) && defAnn.defaultForType().equals( void.class ) ) {
 - throw new AnnotationException(
 - "Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass " +
 - defAnn.typeClass().getName()
 - );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( defAnn.name() ) ) {
 - log.info( "Binding type definition: {}", defAnn.name() );
 - mappings.addTypeDef( defAnn.name(), defAnn.typeClass().getName(), params );
 - }
 - if ( !defAnn.defaultForType().equals( void.class ) ) {
 - log.info( "Binding type definition: {}", defAnn.defaultForType().getName() );
 - mappings.addTypeDef( defAnn.defaultForType().getName(), defAnn.typeClass().getName(), params );
 - }
 - }
 - private static void bindDiscriminatorToPersistentClass(
 - RootClass rootClass,
 - Ejb3DiscriminatorColumn discriminatorColumn,
 - Map<String, Join> secondaryTables,
 - PropertyHolder propertyHolder,
 - Mappings mappings) {
 - 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( mappings, rootClass.getTable() );
 - rootClass.setDiscriminator( discrim );
 - discriminatorColumn.linkWithValue( discrim );
 - discrim.setTypeName( discriminatorColumn.getDiscriminatorTypeName() );
 - rootClass.setPolymorphic( true );
 - log.trace( "Setting discriminator for entity {}", rootClass.getEntityName() );
 - }
 - }
 - /**
 - * @param elements List of {@code ProperyData} instances
 - * @param defaultAccessType The default value access strategy which has to be used in case no explicit local access
 - * strategy is used
 - * @param propertyContainer Metadata about a class and its properties
 - * @param mappings Mapping meta data
 - *
 - * @return the number of id properties found while iterating the elements of {@code annotatedClass} using
 - * the determined access strategy, {@code false} otherwise.
 - */
 - static int addElementsOfClass(
 - List<PropertyData> elements,
 - AccessType defaultAccessType,
 - PropertyContainer propertyContainer,
 - Mappings mappings) {
 - int idPropertyCounter = 0;
 - AccessType accessType = defaultAccessType;
 - if ( propertyContainer.hasExplicitAccessStrategy() ) {
 - accessType = propertyContainer.getExplicitAccessStrategy();
 - }
 - Collection<XProperty> properties = propertyContainer.getProperties( accessType );
 - for ( XProperty p : properties ) {
 - final int currentIdPropertyCounter = addProperty(
 - propertyContainer, p, elements, accessType.getType(), mappings
 - );
 - idPropertyCounter += currentIdPropertyCounter;
 - }
 - return idPropertyCounter;
 - }
 - private static int addProperty(
 - PropertyContainer propertyContainer,
 - XProperty property,
 - List<PropertyData> annElts,
 - String propertyAccessor,
 - Mappings mappings) {
 - final XClass declaringClass = propertyContainer.getDeclaringClass();
 - final XClass entity = propertyContainer.getEntityAtStake();
 - int idPropertyCounter = 0;
 - PropertyData propertyAnnotatedElement = new PropertyInferredData(
 - declaringClass, property, propertyAccessor,
 - mappings.getReflectionManager()
 - );
 - /*
 - * put element annotated by @Id in front
 - * since it has to be parsed before any association by Hibernate
 - */
 - final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
 - if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent( EmbeddedId.class ) ) {
 - annElts.add( 0, propertyAnnotatedElement );
 - /**
 - * The property must be put in hibernate.properties as it's a system wide property. Fixable?
 - * TODO support true/false/default on the property instead of present / not present
 - * TODO is @Column mandatory?
 - * TODO add method support
 - */
 - if ( mappings.isSpecjProprietarySyntaxEnabled() ) {
 - if ( element.isAnnotationPresent( Id.class ) && element.isAnnotationPresent( Column.class ) ) {
 - String columnName = element.getAnnotation( Column.class ).name();
 - for ( XProperty prop : declaringClass.getDeclaredProperties( AccessType.FIELD.getType() ) ) {
 - if ( prop.isAnnotationPresent( JoinColumn.class )
 - && prop.getAnnotation( JoinColumn.class ).name().equals( columnName )
 - && !prop.isAnnotationPresent( MapsId.class ) ) {
 - //create a PropertyData fpr the specJ property holding the mapping
 - PropertyData specJPropertyData = new PropertyInferredData(
 - declaringClass, //same dec
 - prop, // the actual @XToOne property
 - propertyAccessor, //TODO we should get the right accessor but the same as id would do
 - mappings.getReflectionManager()
 - );
 - mappings.addPropertyAnnotatedWithMapsIdSpecj( entity, specJPropertyData, element.toString() );
 - }
 - }
 - }
 - }
 - if ( element.isAnnotationPresent( ManyToOne.class ) || element.isAnnotationPresent( OneToOne.class ) ) {
 - mappings.addToOneAndIdProperty( entity, propertyAnnotatedElement );
 - }
 - idPropertyCounter++;
 - }
 - else {
 - annElts.add( propertyAnnotatedElement );
 - }
 - if ( element.isAnnotationPresent( MapsId.class ) ) {
 - mappings.addPropertyAnnotatedWithMapsId( entity, propertyAnnotatedElement );
 - }
 - return idPropertyCounter;
 - }
 - /*
 - * Process annotation of a particular property
 - */
 - private static void processElementAnnotations(
 - PropertyHolder propertyHolder,
 - Nullability nullability,
 - PropertyData inferredData,
 - HashMap<String, IdGenerator> classGenerators,
 - EntityBinder entityBinder,
 - boolean isIdentifierMapper,
 - boolean isComponentEmbedded,
 - boolean inSecondPass,
 - Mappings mappings,
 - Map<XClass, InheritanceState> inheritanceStatePerClass) throws MappingException {
 - /**
 - * inSecondPass can only be used to apply right away the second pass of a composite-element
 - * Because it's a value type, there is no bidirectional association, hence second pass
 - * ordering does not matter
 - */
 - log.trace(
 - "Processing annotations of {}.{}", propertyHolder.getEntityName(), inferredData.getPropertyName()
 - );
 - final XProperty property = inferredData.getProperty();
 - if ( property.isAnnotationPresent( Parent.class ) ) {
 - if ( propertyHolder.isComponent() ) {
 - propertyHolder.setParentProperty( property.getName() );
 - }
 - else {
 - throw new AnnotationException(
 - "@Parent cannot be applied outside an embeddable object: "
 - + BinderHelper.getPath( propertyHolder, inferredData )
 - );
 - }
 - return;
 - }
 - ColumnsBuilder columnsBuilder = new ColumnsBuilder(
 - propertyHolder, nullability, property, inferredData, entityBinder, mappings
 - ).extractMetadata();
 - Ejb3Column[] columns = columnsBuilder.getColumns();
 - Ejb3JoinColumn[] joinColumns = columnsBuilder.getJoinColumns();
 - final XClass returnedClass = inferredData.getClassOrElement();
 - //prepare PropertyBinder
 - PropertyBinder propertyBinder = new PropertyBinder();
 - propertyBinder.setName( inferredData.getPropertyName() );
 - propertyBinder.setReturnedClassName( inferredData.getTypeName() );
 - propertyBinder.setAccessType( inferredData.getDefaultAccess() );
 - propertyBinder.setHolder( propertyHolder );
 - propertyBinder.setProperty( property );
 - propertyBinder.setReturnedClass( inferredData.getPropertyClass() );
 - propertyBinder.setMappings( mappings );
 - if ( isIdentifierMapper ) {
 - propertyBinder.setInsertable( false );
 - propertyBinder.setUpdatable( false );
 - }
 - propertyBinder.setDeclaringClass( inferredData.getDeclaringClass() );
 - propertyBinder.setEntityBinder( entityBinder );
 - propertyBinder.setInheritanceStatePerClass( inheritanceStatePerClass );
 - boolean isId = !entityBinder.isIgnoreIdAnnotations() &&
 - ( property.isAnnotationPresent( Id.class )
 - || property.isAnnotationPresent( EmbeddedId.class ) );
 - propertyBinder.setId( isId );
 - if ( property.isAnnotationPresent( Version.class ) ) {
 - if ( isIdentifierMapper ) {
 - throw new AnnotationException(
 - "@IdClass class should not have @Version property"
 - );
 - }
 - if ( !( propertyHolder.getPersistentClass() instanceof RootClass ) ) {
 - throw new AnnotationException(
 - "Unable to define/override @Version on a subclass: "
 - + propertyHolder.getEntityName()
 - );
 - }
 - if ( !propertyHolder.isEntity() ) {
 - throw new AnnotationException(
 - "Unable to define @Version on an embedded class: "
 - + propertyHolder.getEntityName()
 - );
 - }
 - log.trace( "{} is a version property", inferredData.getPropertyName() );
 - RootClass rootClass = ( RootClass ) propertyHolder.getPersistentClass();
 - propertyBinder.setColumns( columns );
 - Property prop = propertyBinder.makePropertyValueAndBind();
 - setVersionInformation( property, propertyBinder );
 - rootClass.setVersion( prop );
 - //If version is on a mapped superclass, update the mapping
 - final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
 - inferredData.getDeclaringClass(),
 - inheritanceStatePerClass,
 - mappings
 - );
 - if ( superclass != null ) {
 - superclass.setDeclaredVersion( prop );
 - }
 - else {
 - //we know the property is on the actual entity
 - rootClass.setDeclaredVersion( prop );
 - }
 - SimpleValue simpleValue = ( SimpleValue ) prop.getValue();
 - simpleValue.setNullValue( "undefined" );
 - rootClass.setOptimisticLockMode( Versioning.OPTIMISTIC_LOCK_VERSION );
 - log.trace(
 - "Version name: {}, unsavedValue: {}", rootClass.getVersion().getName(),
 - ( ( SimpleValue ) rootClass.getVersion().getValue() ).getNullValue()
 - );
 - }
 - else {
 - final boolean forcePersist = property.isAnnotationPresent( MapsId.class )
 - || property.isAnnotationPresent( Id.class );
 - if ( property.isAnnotationPresent( ManyToOne.class ) ) {
 - ManyToOne ann = property.getAnnotation( ManyToOne.class );
 - //check validity
 - if ( property.isAnnotationPresent( Column.class )
 - || property.isAnnotationPresent( Columns.class ) ) {
 - throw new AnnotationException(
 - "@Column(s) not allowed on a @ManyToOne property: "
 - + BinderHelper.getPath( propertyHolder, inferredData )
 - );
 - }
 - Cascade hibernateCascade = property.getAnnotation( Cascade.class );
 - NotFound notFound = property.getAnnotation( NotFound.class );
 - boolean ignoreNotFound = notFound != null && notFound.action().equals( NotFoundAction.IGNORE );
 - OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
 - boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals( onDeleteAnn.action() );
 - JoinTable assocTable = propertyHolder.getJoinTable( property );
 - if ( assocTable != null ) {
 - Join join = propertyHolder.addJoin( assocTable, false );
 - for ( Ejb3JoinColumn joinColumn : joinColumns ) {
 - joinColumn.setSecondaryTableName( join.getTable().getName() );
 - }
 - }
 - final boolean mandatory = !ann.optional() || forcePersist;
 - bindManyToOne(
 - getCascadeStrategy( ann.cascade(), hibernateCascade, false, forcePersist ),
 - joinColumns,
 - !mandatory,
 - ignoreNotFound, onDeleteCascade,
 - ToOneBinder.getTargetEntity( inferredData, mappings ),
 - propertyHolder,
 - inferredData, false, isIdentifierMapper,
 - inSecondPass, propertyBinder, mappings
 - );
 - }
 - else if ( property.isAnnotationPresent( OneToOne.class ) ) {
 - OneToOne ann = property.getAnnotation( OneToOne.class );
 - //check validity
 - if ( property.isAnnotationPresent( Column.class )
 - || property.isAnnotationPresent( Columns.class ) ) {
 - throw new AnnotationException(
 - "@Column(s) not allowed on a @OneToOne property: "
 - + BinderHelper.getPath( propertyHolder, inferredData )
 - );
 - }
 - //FIXME support a proper PKJCs
 - boolean trueOneToOne = property.isAnnotationPresent( PrimaryKeyJoinColumn.class )
 - || property.isAnnotationPresent( PrimaryKeyJoinColumns.class );
 - Cascade hibernateCascade = property.getAnnotation( Cascade.class );
 - NotFound notFound = property.getAnnotation( NotFound.class );
 - boolean ignoreNotFound = notFound != null && notFound.action().equals( NotFoundAction.IGNORE );
 - OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
 - boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals( onDeleteAnn.action() );
 - JoinTable assocTable = propertyHolder.getJoinTable( property );
 - if ( assocTable != null ) {
 - Join join = propertyHolder.addJoin( assocTable, false );
 - for ( Ejb3JoinColumn joinColumn : joinColumns ) {
 - joinColumn.setSecondaryTableName( join.getTable().getName() );
 - }
 - }
 - //MapsId means the columns belong to the pk => not null
 - //@PKJC must be constrained
 - final boolean mandatory = !ann.optional() || forcePersist || trueOneToOne;
 - bindOneToOne(
 - getCascadeStrategy( ann.cascade(), hibernateCascade, ann.orphanRemoval(), forcePersist ),
 - joinColumns,
 - !mandatory,
 - getFetchMode( ann.fetch() ),
 - ignoreNotFound, onDeleteCascade,
 - ToOneBinder.getTargetEntity( inferredData, mappings ),
 - propertyHolder,
 - inferredData,
 - ann.mappedBy(),
 - trueOneToOne,
 - isIdentifierMapper,
 - inSecondPass,
 - propertyBinder,
 - mappings
 - );
 - }
 - else if ( property.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
 - //check validity
 - if ( property.isAnnotationPresent( Column.class )
 - || property.isAnnotationPresent( Columns.class ) ) {
 - throw new AnnotationException(
 - "@Column(s) not allowed on a @Any property: "
 - + BinderHelper.getPath( propertyHolder, inferredData )
 - );
 - }
 - Cascade hibernateCascade = property.getAnnotation( Cascade.class );
 - OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
 - boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals( onDeleteAnn.action() );
 - JoinTable assocTable = propertyHolder.getJoinTable( property );
 - if ( assocTable != null ) {
 - Join join = propertyHolder.addJoin( assocTable, false );
 - for ( Ejb3JoinColumn joinColumn : joinColumns ) {
 - joinColumn.setSecondaryTableName( join.getTable().getName() );
 - }
 - }
 - bindAny(
 - getCascadeStrategy( null, hibernateCascade, false, forcePersist ),
 - //@Any has not cascade attribute
 - joinColumns,
 - onDeleteCascade,
 - nullability,
 - propertyHolder,
 - inferredData,
 - entityBinder,
 - isIdentifierMapper,
 - mappings
 - );
 - }
 - else if ( property.isAnnotationPresent( OneToMany.class )
 - || property.isAnnotationPresent( ManyToMany.class )
 - || property.isAnnotationPresent( CollectionOfElements.class ) //legacy Hibernate
 - || property.isAnnotationPresent( ElementCollection.class )
 - || property.isAnnotationPresent( ManyToAny.class ) ) {
 - OneToMany oneToManyAnn = property.getAnnotation( OneToMany.class );
 - ManyToMany manyToManyAnn = property.getAnnotation( ManyToMany.class );
 - ElementCollection elementCollectionAnn = property.getAnnotation( ElementCollection.class );
 - CollectionOfElements collectionOfElementsAnn = property.getAnnotation( CollectionOfElements.class ); //legacy hibernate
 - final IndexColumn indexColumn;
 - if ( property.isAnnotationPresent( OrderColumn.class ) ) {
 - indexColumn = IndexColumn.buildColumnFromAnnotation(
 - property.getAnnotation( OrderColumn.class ),
 - propertyHolder,
 - inferredData,
 - entityBinder.getSecondaryTables(),
 - mappings
 - );
 - }
 - else {
 - //if @IndexColumn is not there, the generated IndexColumn is an implicit column and not used.
 - //so we can leave the legacy processing as the default
 - indexColumn = IndexColumn.buildColumnFromAnnotation(
 - property.getAnnotation( org.hibernate.annotations.IndexColumn.class ),
 - propertyHolder,
 - inferredData,
 - mappings
 - );
 - }
 - CollectionBinder collectionBinder = CollectionBinder.getCollectionBinder(
 - propertyHolder.getEntityName(),
 - property,
 - !indexColumn.isImplicit(),
 - property.isAnnotationPresent( CollectionOfElements.class )
 - || property.isAnnotationPresent( org.hibernate.annotations.MapKey.class )
 - || property.isAnnotationPresent( MapKeyType.class )
 - // || property.isAnnotationPresent( ManyToAny.class )
 - );
 - collectionBinder.setIndexColumn( indexColumn );
 - collectionBinder.setMapKey( property.getAnnotation( MapKey.class ) );
 - collectionBinder.setPropertyName( inferredData.getPropertyName() );
 - BatchSize batchAnn = property.getAnnotation( BatchSize.class );
 - collectionBinder.setBatchSize( batchAnn );
 - javax.persistence.OrderBy ejb3OrderByAnn = property.getAnnotation( javax.persistence.OrderBy.class );
 - OrderBy orderByAnn = property.getAnnotation( OrderBy.class );
 - collectionBinder.setEjb3OrderBy( ejb3OrderByAnn );
 - collectionBinder.setSqlOrderBy( orderByAnn );
 - Sort sortAnn = property.getAnnotation( Sort.class );
 - collectionBinder.setSort( sortAnn );
 - Cache cachAnn = property.getAnnotation( Cache.class );
 - collectionBinder.setCache( cachAnn );
 - collectionBinder.setPropertyHolder( propertyHolder );
 - Cascade hibernateCascade = property.getAnnotation( Cascade.class );
 - NotFound notFound = property.getAnnotation( NotFound.class );
 - boolean ignoreNotFound = notFound != null && notFound.action().equals( NotFoundAction.IGNORE );
 - collectionBinder.setIgnoreNotFound( ignoreNotFound );
 - collectionBinder.setCollectionType( inferredData.getProperty().getElementClass() );
 - collectionBinder.setMappings( mappings );
 - collectionBinder.setAccessType( inferredData.getDefaultAccess() );
 - Ejb3Column[] elementColumns;
 - //do not use "element" if you are a JPA 2 @ElementCollection only for legacy Hibernate mappings
 - boolean isJPA2ForValueMapping = property.isAnnotationPresent( ElementCollection.class );
 - PropertyData virtualProperty = isJPA2ForValueMapping ? inferredData : new WrappedInferredData(
 - inferredData, "element"
 - );
 - if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent(
 - Formula.class
 - ) ) {
 - Column ann = property.getAnnotation( Column.class );
 - Formula formulaAnn = property.getAnnotation( Formula.class );
 - elementColumns = Ejb3Column.buildColumnFromAnnotation(
 - new Column[] { ann },
 - formulaAnn,
 - nullability,
 - propertyHolder,
 - virtualProperty,
 - entityBinder.getSecondaryTables(),
 - mappings
 - );
 - }
 - else if ( property.isAnnotationPresent( Columns.class ) ) {
 - Columns anns = property.getAnnotation( Columns.class );
 - elementColumns = Ejb3Column.buildColumnFromAnnotation(
 - anns.columns(), null, nullability, propertyHolder, virtualProperty,
 - entityBinder.getSecondaryTables(), mappings
 - );
 - }
 - else {
 - elementColumns = Ejb3Column.buildColumnFromAnnotation(
 - null,
 - null,
 - nullability,
 - propertyHolder,
 - virtualProperty,
 - entityBinder.getSecondaryTables(),
 - mappings
 - );
 - }
 - {
 - Column[] keyColumns = null;
 - //JPA 2 has priority and has different default column values, differenciate legacy from JPA 2
 - Boolean isJPA2 = null;
 - if ( property.isAnnotationPresent( MapKeyColumn.class ) ) {
 - isJPA2 = Boolean.TRUE;
 - keyColumns = new Column[] { new MapKeyColumnDelegator( property.getAnnotation( MapKeyColumn.class ) ) };
 - }
 - else if ( property.isAnnotationPresent( org.hibernate.annotations.MapKey.class ) ) {
 - if ( isJPA2 == null ) {
 - isJPA2 = Boolean.FALSE;
 - }
 - keyColumns = property.getAnnotation( org.hibernate.annotations.MapKey.class ).columns();
 - }
 - //not explicitly legacy
 - if ( isJPA2 == null ) {
 - isJPA2 = Boolean.TRUE;
 - }
 - //nullify empty array
 - keyColumns = keyColumns != null && keyColumns.length > 0 ? keyColumns : null;
 - //"mapkey" is the legacy column name of the key column pre JPA 2
 - PropertyData mapKeyVirtualProperty = new WrappedInferredData( inferredData, "mapkey" );
 - Ejb3Column[] mapColumns = Ejb3Column.buildColumnFromAnnotation(
 - keyColumns,
 - null,
 - Nullability.FORCED_NOT_NULL,
 - propertyHolder,
 - isJPA2 ? inferredData : mapKeyVirtualProperty,
 - isJPA2 ? "_KEY" : null,
 - entityBinder.getSecondaryTables(),
 - mappings
 - );
 - collectionBinder.setMapKeyColumns( mapColumns );
 - }
 - {
 - JoinColumn[] joinKeyColumns = null;
 - //JPA 2 has priority and has different default column values, differenciate legacy from JPA 2
 - Boolean isJPA2 = null;
 - if ( property.isAnnotationPresent( MapKeyJoinColumns.class ) ) {
 - isJPA2 = Boolean.TRUE;
 - final MapKeyJoinColumn[] mapKeyJoinColumns = property.getAnnotation( MapKeyJoinColumns.class )
 - .value();
 - joinKeyColumns = new JoinColumn[mapKeyJoinColumns.length];
 - int index = 0;
 - for ( MapKeyJoinColumn joinColumn : mapKeyJoinColumns ) {
 - joinKeyColumns[index] = new MapKeyJoinColumnDelegator( joinColumn );
 - index++;
 - }
 - if ( property.isAnnotationPresent( MapKeyJoinColumn.class ) ) {
 - throw new AnnotationException(
 - "@MapKeyJoinColumn and @MapKeyJoinColumns used on the same property: "
 - + BinderHelper.getPath( propertyHolder, inferredData )
 - );
 - }
 - }
 - else if ( property.isAnnotationPresent( MapKeyJoinColumn.class ) ) {
 - isJPA2 = Boolean.TRUE;
 - joinKeyColumns = new JoinColumn[] {
 - new MapKeyJoinColumnDelegator(
 - property.getAnnotation(
 - MapKeyJoinColumn.class
 - )
 - )
 - };
 - }
 - else if ( property.isAnnotationPresent( org.hibernate.annotations.MapKeyManyToMany.class ) ) {
 - if ( isJPA2 == null ) {
 - isJPA2 = Boolean.FALSE;
 - }
 - joinKeyColumns = property.getAnnotation( org.hibernate.annotations.MapKeyManyToMany.class )
 - .joinColumns();
 - }
 - //not explicitly legacy
 - if ( isJPA2 == null ) {
 - isJPA2 = Boolean.TRUE;
 - }
 - PropertyData mapKeyVirtualProperty = new WrappedInferredData( inferredData, "mapkey" );
 - Ejb3JoinColumn[] mapJoinColumns = Ejb3JoinColumn.buildJoinColumnsWithDefaultColumnSuffix(
 - joinKeyColumns,
 - null,
 - entityBinder.getSecondaryTables(),
 - propertyHolder,
 - isJPA2 ? inferredData.getPropertyName() : mapKeyVirtualProperty.getPropertyName(),
 - isJPA2 ? "_KEY" : null,
 - mappings
 - );
 - collectionBinder.setMapKeyManyToManyColumns( mapJoinColumns );
 - }
 - //potential element
 - collectionBinder.setEmbedded( property.isAnnotationPresent( Embedded.class ) );
 - collectionBinder.setElementColumns( elementColumns );
 - collectionBinder.setProperty( property );
 - //TODO enhance exception with @ManyToAny and @CollectionOfElements
 - if ( oneToManyAnn != null && manyToManyAnn != null ) {
 - throw new AnnotationException(
 - "@OneToMany and @ManyToMany on the same property is not allowed: "
 - + propertyHolder.getEntityName() + "." + inferredData.getPropertyName()
 - );
 - }
 - String mappedBy = null;
 - if ( oneToManyAnn != null ) {
 - for ( Ejb3JoinColumn column : joinColumns ) {
 - if ( column.isSecondary() ) {
 - throw new NotYetImplementedException( "Collections having FK in secondary table" );
 - }
 - }
 - collectionBinder.setFkJoinColumns( joinColumns );
 - mappedBy = oneToManyAnn.mappedBy();
 - collectionBinder.setTargetEntity(
 - mappings.getReflectionManager().toXClass( oneToManyAnn.targetEntity() )
 - );
 - collectionBinder.setCascadeStrategy(
 - getCascadeStrategy(
 - oneToManyAnn.cascade(), hibernateCascade, oneToManyAnn.orphanRemoval(), false
 - )
 - );
 - collectionBinder.setOneToMany( true );
 - }
 - else if ( elementCollectionAnn != null
 - || collectionOfElementsAnn != null //Hibernate legacy
 - ) {
 - for ( Ejb3JoinColumn column : joinColumns ) {
 - if ( column.isSecondary() ) {
 - throw new NotYetImplementedException( "Collections having FK in secondary table" );
 - }
 - }
 - collectionBinder.setFkJoinColumns( joinColumns );
 - mappedBy = "";
 - final Class<?> targetElement = elementCollectionAnn != null ?
 - elementCollectionAnn.targetClass() :
 - collectionOfElementsAnn.targetElement();
 - collectionBinder.setTargetEntity(
 - mappings.getReflectionManager().toXClass( targetElement )
 - );
 - //collectionBinder.setCascadeStrategy( getCascadeStrategy( embeddedCollectionAnn.cascade(), hibernateCascade ) );
 - collectionBinder.setOneToMany( true );
 - }
 - else if ( manyToManyAnn != null ) {
 - mappedBy = manyToManyAnn.mappedBy();
 - collectionBinder.setTargetEntity(
 - mappings.getReflectionManager().toXClass( manyToManyAnn.targetEntity() )
 - );
 - collectionBinder.setCascadeStrategy(
 - getCascadeStrategy(
 - manyToManyAnn.cascade(), hibernateCascade, false, false
 - )
 - );
 - collectionBinder.setOneToMany( false );
 - }
 - else if ( property.isAnnotationPresent( ManyToAny.class ) ) {
 - mappedBy = "";
 - collectionBinder.setTargetEntity(
 - mappings.getReflectionManager().toXClass( void.class )
 - );
 - collectionBinder.setCascadeStrategy( getCascadeStrategy( null, hibernateCascade, false, false ) );
 - collectionBinder.setOneToMany( false );
 - }
 - collectionBinder.setMappedBy( mappedBy );
 - bindJoinedTableAssociation(
 - property, mappings, entityBinder, collectionBinder, propertyHolder, inferredData, mappedBy
 - );
 - OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
 - boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals( onDeleteAnn.action() );
 - collectionBinder.setCascadeDeleteEnabled( onDeleteCascade );
 - if ( isIdentifierMapper ) {
 - collectionBinder.setInsertable( false );
 - collectionBinder.setUpdatable( false );
 - }
 - if ( property.isAnnotationPresent( CollectionId.class ) ) { //do not compute the generators unless necessary
 - HashMap<String, IdGenerator> localGenerators = ( HashMap<String, IdGenerator> ) classGenerators.clone();
 - localGenerators.putAll( buildLocalGenerators( property, mappings ) );
 - collectionBinder.setLocalGenerators( localGenerators );
 - }
 - collectionBinder.setInheritanceStatePerClass( inheritanceStatePerClass );
 - collectionBinder.setDeclaringClass( inferredData.getDeclaringClass() );
 - collectionBinder.bind();
 - }
 - //Either a regular property or a basic @Id or @EmbeddedId while not ignoring id annotations
 - else if ( !isId || !entityBinder.isIgnoreIdAnnotations() ) {
 - //define whether the type is a component or not
 - boolean isComponent = false;
 - //Overrides from @MapsId if needed
 - boolean isOverridden = false;
 - if ( isId || propertyHolder.isOrWithinEmbeddedId() || propertyHolder.isInIdClass() ) {
 - //the associated entity could be using an @IdClass making the overridden property a component
 - final PropertyData overridingProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(
 - isId, propertyHolder, property.getName(), mappings
 - );
 - if ( overridingProperty != null ) {
 - isOverridden = true;
 - final InheritanceState state = inheritanceStatePerClass.get( overridingProperty.getClassOrElement() );
 - if ( state != null ) {
 - isComponent = isComponent || state.hasIdClassOrEmbeddedId();
 - }
 - //Get the new column
 - columns = columnsBuilder.overrideColumnFromMapperOrMapsIdProperty( isId );
 - }
 - }
 - isComponent = isComponent
 - || property.isAnnotationPresent( Embedded.class )
 - || property.isAnnotationPresent( EmbeddedId.class )
 - || returnedClass.isAnnotationPresent( Embeddable.class );
 - if ( isComponent ) {
 - String referencedEntityName = null;
 - if ( isOverridden ) {
 - final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(
 - isId, propertyHolder, property.getName(), mappings
 - );
 - referencedEntityName = mapsIdProperty.getClassOrElementName();
 - }
 - AccessType propertyAccessor = entityBinder.getPropertyAccessor( property );
 - propertyBinder = bindComponent(
 - inferredData,
 - propertyHolder,
 - propertyAccessor,
 - entityBinder,
 - isIdentifierMapper,
 - mappings,
 - isComponentEmbedded,
 - isId,
 - inheritanceStatePerClass,
 - referencedEntityName,
 - isOverridden ? ( Ejb3JoinColumn[] ) columns : null
 - );
 - }
 - else {
 - //provide the basic property mapping
 - boolean optional = true;
 - boolean lazy = false;
 - if ( property.isAnnotationPresent( Basic.class ) ) {
 - Basic ann = property.getAnnotation( Basic.class );
 - optional = ann.optional();
 - lazy = ann.fetch() == FetchType.LAZY;
 - }
 - //implicit type will check basic types and Serializable classes
 - if ( isId || ( !optional && nullability != Nullability.FORCED_NULL ) ) {
 - //force columns to not null
 - for ( Ejb3Column col : columns ) {
 - col.forceNotNull();
 - }
 - }
 - propertyBinder.setLazy( lazy );
 - propertyBinder.setColumns( columns );
 - if ( isOverridden ) {
 - final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(
 - isId, propertyHolder, property.getName(), mappings
 - );
 - propertyBinder.setReferencedEntityName( mapsIdProperty.getClassOrElementName() );
 - }
 - propertyBinder.makePropertyValueAndBind();
 - }
 - if ( isOverridden ) {
 - final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(
 - isId, propertyHolder, property.getName(), mappings
 - );
 - Map<String, IdGenerator> localGenerators = ( HashMap<String, IdGenerator> ) classGenerators.clone();
 - final IdGenerator foreignGenerator = new IdGenerator();
 - foreignGenerator.setIdentifierGeneratorStrategy( "assigned" );
 - foreignGenerator.setName( "Hibernate-local--foreign generator" );
 - foreignGenerator.setIdentifierGeneratorStrategy( "foreign" );
 - foreignGenerator.addParam( "property", mapsIdProperty.getPropertyName() );
 - localGenerators.put( foreignGenerator.getName(), foreignGenerator );
 - BinderHelper.makeIdGenerator(
 - ( SimpleValue ) propertyBinder.getValue(),
 - foreignGenerator.getIdentifierGeneratorStrategy(),
 - foreignGenerator.getName(),
 - mappings,
 - localGenerators
 - );
 - }
 - if ( isId ) {
 - //components and regular basic types create SimpleValue objects
 - final SimpleValue value = ( SimpleValue ) propertyBinder.getValue();
 - if ( !isOverridden ) {
 - processId(
 - propertyHolder,
 - inferredData,
 - value,
 - classGenerators,
 - isIdentifierMapper,
 - mappings
 - );
 - }
 - }
 - }
 - }
 - //init index
 - //process indexes after everything: in second pass, many to one has to be done before indexes
 - Index index = property.getAnnotation( Index.class );
 - if ( index != null ) {
 - if ( joinColumns != null ) {
 - for ( Ejb3Column column : joinColumns ) {
 - column.addIndex( index, inSecondPass );
 - }
 - }
 - else {
 - if ( columns != null ) {
 - for ( Ejb3Column column : columns ) {
 - column.addIndex( index, inSecondPass );
 - }
 - }
 - }
 - }
 - NaturalId naturalIdAnn = property.getAnnotation( NaturalId.class );
 - if ( naturalIdAnn != null ) {
 - if ( joinColumns != null ) {
 - for ( Ejb3Column column : joinColumns ) {
 - column.addUniqueKey( "_UniqueKey", inSecondPass );
 - }
 - }
 - else {
 - for ( Ejb3Column column : columns ) {
 - column.addUniqueKey( "_UniqueKey", inSecondPass );
 - }
 - }
 - }
 - //添加自定义注释的处理
 - CommentBinder.bindColumnComment(property, columns);
 - //CommentBinder.bindTableComment(clazzToProcess, persistentClass);
 - //CommentBinder.bindColumnComment(property, column);
 - }
 - private static void setVersionInformation(XProperty property, PropertyBinder propertyBinder) {
 - propertyBinder.getSimpleValueBinder().setVersion( true );
 - if(property.isAnnotationPresent( Source.class )) {
 - Source source = property.getAnnotation( Source.class );
 - propertyBinder.getSimpleValueBinder().setTimestampVersionType( source.value().typeName() );
 - }
 - }
 - private static void processId(
 - PropertyHolder propertyHolder,
 - PropertyData inferredData,
 - SimpleValue idValue,
 - HashMap<String, IdGenerator> classGenerators,
 - boolean isIdentifierMapper,
 - Mappings mappings) {
 - if ( isIdentifierMapper ) {
 - throw new AnnotationException(
 - "@IdClass class should not have @Id nor @EmbeddedId properties: "
 - + BinderHelper.getPath( propertyHolder, inferredData )
 - );
 - }
 - XClass returnedClass = inferredData.getClassOrElement();
 - XProperty property = inferredData.getProperty();
 - //clone classGenerator and override with local values
 - HashMap<String, IdGenerator> localGenerators = ( HashMap<String, IdGenerator> ) classGenerators.clone();
 - localGenerators.putAll( buildLocalGenerators( property, mappings ) );
 - //manage composite related metadata
 - //guess if its a component and find id data access (property, field etc)
 - final boolean isComponent = returnedClass.isAnnotationPresent( Embeddable.class )
 - || property.isAnnotationPresent( EmbeddedId.class );
 - GeneratedValue generatedValue = property.getAnnotation( GeneratedValue.class );
 - String generatorType = generatedValue != null ?
 - generatorType( generatedValue.strategy(), mappings ) :
 - "assigned";
 - String generatorName = generatedValue != null ?
 - generatedValue.generator() :
 - BinderHelper.ANNOTATION_STRING_DEFAULT;
 - if ( isComponent ) {
 - generatorType = "assigned";
 - } //a component must not have any generator
 - BinderHelper.makeIdGenerator( idValue, generatorType, generatorName, mappings, localGenerators );
 - log.trace(
 - "Bind {} on {}", ( isComponent ? "@EmbeddedId" : "@Id" ), inferredData.getPropertyName()
 - );
 - }
 - //TODO move that to collection binder?
 - private static void bindJoinedTableAssociation(
 - XProperty property,
 - Mappings mappings,
 - EntityBinder entityBinder,
 - CollectionBinder collectionBinder,
 - PropertyHolder propertyHolder,
 - PropertyData inferredData,
 - String mappedBy) {
 - TableBinder associationTableBinder = new TableBinder();
 - JoinColumn[] annJoins;
 - JoinColumn[] annInverseJoins;
 - JoinTable assocTable = propertyHolder.getJoinTable( property );
 - CollectionTable collectionTable = property.getAnnotation( CollectionTable.class );
 - if ( assocTable != null || collectionTable != null ) {
 - final String catalog;
 - final String schema;
 - final String tableName;
 - final UniqueConstraint[] uniqueConstraints;
 - final JoinColumn[] joins;
 - final JoinColumn[] inverseJoins;
 - //JPA 2 has priority
 - if ( collectionTable != null ) {
 - catalog = collectionTable.catalog();
 - schema = collectionTable.schema();
 - tableName = collectionTable.name();
 - uniqueConstraints = collectionTable.uniqueConstraints();
 - joins = collectionTable.joinColumns();
 - inverseJoins = null;
 - }
 - else {
 - catalog = assocTable.catalog();
 - schema = assocTable.schema();
 - tableName = assocTable.name();
 - uniqueConstraints = assocTable.uniqueConstraints();
 - joins = assocTable.joinColumns();
 - inverseJoins = assocTable.inverseJoinColumns();
 - }
 - collectionBinder.setExplicitAssociationTable( true );
 - if ( !BinderHelper.isEmptyAnnotationValue( schema ) ) {
 - associationTableBinder.setSchema( schema );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( catalog ) ) {
 - associationTableBinder.setCatalog( catalog );
 - }
 - if ( !BinderHelper.isEmptyAnnotationValue( tableName ) ) {
 - associationTableBinder.setName( tableName );
 - }
 - associationTableBinder.setUniqueConstraints( uniqueConstraints );
 - //set check constaint in the second pass
 - annJoins = joins.length == 0 ? null : joins;
 - annInverseJoins = inverseJoins == null || inverseJoins.length == 0 ? null : inverseJoins;
 - }
 - else {
 - annJoins = null;
 - annInverseJoins = null;
 - }
 - Ejb3JoinColumn[] joinColumns = Ejb3JoinColumn.buildJoinTableJoinColumns(
 - annJoins, entityBinder.getSecondaryTables(), propertyHolder, inferredData.getPropertyName(), mappedBy,
 - mappings
 - );
 - Ejb3JoinColumn[] inverseJoinColumns = Ejb3JoinColumn.buildJoinTableJoinColumns(
 - annInverseJoins, entityBinder.getSecondaryTables(), propertyHolder, inferredData.getPropertyName(),
 - mappedBy, mappings
 - );
 - associationTableBinder.setMappings( mappings );
 - collectionBinder.setTableBinder( associationTableBinder );
 - collectionBinder.setJoinColumns( joinColumns );
 - collectionBinder.setInverseJoinColumns( inverseJoinColumns );
 - }
 - private static PropertyBinder bindComponent(
 - PropertyData inferredData,
 - PropertyHolder propertyHolder,
 - AccessType propertyAccessor,
 - EntityBinder entityBinder,
 - boolean isIdentifierMapper,
 - Mappings mappings,
 - boolean isComponentEmbedded,
 - boolean isId, //is a identifier
 - Map<XClass, InheritanceState> inheritanceStatePerClass,
 - String referencedEntityName, //is a component who is overridden by a @MapsId
 - Ejb3JoinColumn[] columns) {
 - Component comp;
 - if ( referencedEntityName != null ) {
 - comp = createComponent( propertyHolder, inferredData, isComponentEmbedded, isIdentifierMapper, mappings );
 - SecondPass sp = new CopyIdentifierComponentSecondPass(
 - comp,
 - referencedEntityName,
 - columns,
 - mappings
 - );
 - mappings.addSecondPass( sp );
 - }
 - else {
 - comp = fillComponent(
 - propertyHolder, inferredData, propertyAccessor, !isId, entityBinder,
 - isComponentEmbedded, isIdentifierMapper,
 - false, mappings, inheritanceStatePerClass
 - );
 - }
 - if ( isId ) {
 - comp.setKey( true );
 - if ( propertyHolder.getPersistentClass().getIdentifier() != null ) {
 - throw new AnnotationException(
 - comp.getComponentClassName()
 - + " must not have @Id properties when used as an @EmbeddedId: "
 - + BinderHelper.getPath( propertyHolder, inferredData )
 - );
 - }
 - if ( referencedEntityName == null && comp.getPropertySpan() == 0 ) {
 - throw new AnnotationException(
 - comp.getComponentClassName()
 - + " has no persistent id property: "
 - + BinderHelper.getPath( propertyHolder, inferredData )
 - );
 - }
 - }
 - XProperty property = inferredData.getProperty();
 - setupComponentTuplizer( property, comp );
 - PropertyBinder binder = new PropertyBinder();
 - binder.setName( inferredData.getPropertyName() );
 - binder.setValue( comp );
 - binder.setProperty( inferredData.getProperty() );
 - binder.setAccessType( inferredData.getDefaultAccess() );
 - binder.setEmbedded( isComponentEmbedded );
 - binder.setHolder( propertyHolder );
 - binder.setId( isId );
 - binder.setEntityBinder( entityBinder );
 - binder.setInheritanceStatePerClass( inheritanceStatePerClass );
 - binder.setMappings( mappings );
 - binder.makePropertyAndBind();
 - return binder;
 - }
 - public static Component fillComponent(
 - PropertyHolder propertyHolder,
 - PropertyData inferredData,
 - AccessType propertyAccessor,
 - boolean isNullable,
 - EntityBinder entityBinder,
 - boolean isComponentEmbedded,
 - boolean isIdentifierMapper,
 - boolean inSecondPass,
 - Mappings mappings,
 - Map<XClass, InheritanceState> inheritanceStatePerClass) {
 - return fillComponent(
 - propertyHolder, inferredData, null, propertyAccessor,
 - isNullable, entityBinder, isComponentEmbedded, isIdentifierMapper, inSecondPass, mappings,
 - inheritanceStatePerClass
 - );
 - }
 - public static Component fillComponent(
 - PropertyHolder propertyHolder,
 - PropertyData inferredData,
 - PropertyData baseInferredData, //base inferred data correspond to the entity reproducing inferredData's properties (ie IdClass)
 - AccessType propertyAccessor,
 - boolean isNullable,
 - EntityBinder entityBinder,
 - boolean isComponentEmbedded,
 - boolean isIdentifierMapper,
 - boolean inSecondPass,
 - Mappings mappings,
 - Map<XClass, InheritanceState> inheritanceStatePerClass) {
 - /**
 - * inSecondPass can only be used to apply right away the second pass of a composite-element
 - * Because it's a value type, there is no bidirectional association, hence second pass
 - * ordering does not matter
 - */
 - Component comp = createComponent( propertyHolder, inferredData, isComponentEmbedded, isIdentifierMapper, mappings );
 - String subpath = BinderHelper.getPath( propertyHolder, inferredData );
 - log.trace( "Binding component with path: {}", subpath );
 - PropertyHolder subHolder = PropertyHolderBuilder.buildPropertyHolder(
 - comp, subpath,
 - inferredData, propertyHolder, mappings
 - );
 - final XClass xClassProcessed = inferredData.getPropertyClass();
 - List<PropertyData> classElements = new ArrayList<PropertyData>();
 - XClass returnedClassOrElement = inferredData.getClassOrElement();
 - List<PropertyData> baseClassElements = null;
 - Map<String, PropertyData> orderedBaseClassElements = new HashMap<String, PropertyData>();
 - XClass baseReturnedClassOrElement;
 - if ( baseInferredData != null ) {
 - baseClassElements = new ArrayList<PropertyData>();
 - baseReturnedClassOrElement = baseInferredData.getClassOrElement();
 - bindTypeDefs( baseReturnedClassOrElement, mappings );
 - PropertyContainer propContainer = new PropertyContainer( baseReturnedClassOrElement, xClassProcessed );
 - addElementsOfClass( baseClassElements, propertyAccessor, propContainer, mappings );
 - for ( PropertyData element : baseClassElements ) {
 - orderedBaseClassElements.put( element.getPropertyName(), element );
 - }
 - }
 - //embeddable elements can have type defs
 - bindTypeDefs( returnedClassOrElement, mappings );
 - PropertyContainer propContainer = new PropertyContainer( returnedClassOrElement, xClassProcessed );
 - addElementsOfClass( classElements, propertyAccessor, propContainer, mappings );
 - //add elements of the embeddable superclass
 - XClass superClass = xClassProcessed.getSuperclass();
 - while ( superClass != null && superClass.isAnnotationPresent( MappedSuperclass.class ) ) {
 - //FIXME: proper support of typevariables incl var resolved at upper levels
 - propContainer = new PropertyContainer( superClass, xClassProcessed );
 - addElementsOfClass( classElements, propertyAccessor, propContainer, mappings );
 - superClass = superClass.getSuperclass();
 - }
 - if ( baseClassElements != null ) {
 - //useful to avoid breaking pre JPA 2 mappings
 - if ( !hasAnnotationsOnIdClass( xClassProcessed ) ) {
 - for ( int i = 0; i < classElements.size(); i++ ) {
 - final PropertyData idClassPropertyData = classElements.get( i );
 - final PropertyData entityPropertyData = orderedBaseClassElements.get( idClassPropertyData.getPropertyName() );
 - if ( propertyHolder.isInIdClass() ) {
 - if ( entityPropertyData == null ) {
 - throw new AnnotationException(
 - "Property of @IdClass not found in entity "
 - + baseInferredData.getPropertyClass().getName() + ": "
 - + idClassPropertyData.getPropertyName()
 - );
 - }
 - final boolean hasXToOneAnnotation = entityPropertyData.getProperty()
 - .isAnnotationPresent( ManyToOne.class )
 - || entityPropertyData.getProperty().isAnnotationPresent( OneToOne.class );
 - final boolean isOfDifferentType = !entityPropertyData.getClassOrElement()
 - .equals( idClassPropertyData.getClassOrElement() );
 - if ( hasXToOneAnnotation && isOfDifferentType ) {
 - //don't replace here as we need to use the actual original return type
 - //the annotation overriding will be dealt with by a mechanism similar to @MapsId
 - }
 - else {
 - classElements.set( i, entityPropertyData ); //this works since they are in the same order
 - }
 - }
 - else {
 - classElements.set( i, entityPropertyData ); //this works since they are in the same order
 - }
 - }
 - }
 - }
 - for ( PropertyData propertyAnnotatedElement : classElements ) {
 - processElementAnnotations(
 - subHolder, isNullable ?
 - Nullability.NO_CONSTRAINT :
 - Nullability.FORCED_NOT_NULL,
 - propertyAnnotatedElement,
 - new HashMap<String, IdGenerator>(), entityBinder, isIdentifierMapper, isComponentEmbedded,
 - inSecondPass, mappings, inheritanceStatePerClass
 - );
 - XProperty property = propertyAnnotatedElement.getProperty();
 - if ( property.isAnnotationPresent( GeneratedValue.class ) &&
 - property.isAnnotationPresent( Id.class ) ) {
 - //clone classGenerator and override with local values
 - Map<String, IdGenerator> localGenerators = new HashMap<String, IdGenerator>();
 - localGenerators.putAll( buildLocalGenerators( property, mappings ) );
 - GeneratedValue generatedValue = property.getAnnotation( GeneratedValue.class );
 - String generatorType = generatedValue != null ? generatorType(
 - generatedValue.strategy(), mappings
 - ) : "assigned";
 - String generator = generatedValue != null ? generatedValue.generator() : BinderHelper.ANNOTATION_STRING_DEFAULT;
 - BinderHelper.makeIdGenerator(
 - ( SimpleValue ) comp.getProperty( property.getName() ).getValue(),
 - generatorType,
 - generator,
 - mappings,
 - localGenerators
 - );
 - }
 - }
 - return comp;
 - }
 - public static Component createComponent(
 - PropertyHolder propertyHolder,
 - PropertyData inferredData,
 - boolean isComponentEmbedded,
 - boolean isIdentifierMapper,
 - Mappings mappings) {
 - Component comp = new Component( mappings, propertyHolder.getPersistentClass() );
 - comp.setEmbedded( isComponentEmbedded );
 - //yuk
 - comp.setTable( propertyHolder.getTable() );
 - //FIXME shouldn't identifier mapper use getClassOrElementName? Need to be checked.
 - if ( isIdentifierMapper || ( isComponentEmbedded && inferredData.getPropertyName() == null ) ) {
 - comp.setComponentClassName( comp.getOwner().getClassName() );
 - }
 - else {
 - comp.setComponentClassName( inferredData.getClassOrElementName() );
 - }
 - comp.setNodeName( inferredData.getPropertyName() );
 - return comp;
 - }
 - private static void bindIdClass(
 - String generatorType,
 - String generatorName,
 - PropertyData inferredData,
 - PropertyData baseInferredData,
 - Ejb3Column[] columns,
 - PropertyHolder propertyHolder,
 - boolean isComposite,
 - AccessType propertyAccessor,
 - EntityBinder entityBinder,
 - boolean isEmbedded,
 - boolean isIdentifierMapper,
 - Mappings mappings,
 - Map<XClass, InheritanceState> inheritanceStatePerClass) {
 - /*
 - * Fill simple value and property since and Id is a property
 - */
 - PersistentClass persistentClass = propertyHolder.getPersistentClass();
 - if ( !( persistentClass instanceof RootClass ) ) {
 - throw new AnnotationException(
 - "Unable to define/override @Id(s) on a subclass: "
 - + propertyHolder.getEntityName()
 - );
 - }
 - RootClass rootClass = ( RootClass ) persistentClass;
 - String persistentClassName = rootClass.getClassName();
 - SimpleValue id;
 - final String propertyName = inferredData.getPropertyName();
 - HashMap<String, IdGenerator> localGenerators = new HashMap<String, IdGenerator>();
 - if ( isComposite ) {
 - id = fillComponent(
 - propertyHolder, inferredData, baseInferredData, propertyAccessor,
 - false, entityBinder, isEmbedded, isIdentifierMapper, false, mappings, inheritanceStatePerClass
 - );
 - Component componentId = ( Component ) id;
 - componentId.setKey( true );
 - if ( rootClass.getIdentifier() != null ) {
 - throw new AnnotationException( componentId.getComponentClassName() + " must not have @Id properties when used as an @EmbeddedId" );
 - }
 - if ( componentId.getPropertySpan() == 0 ) {
 - throw new AnnotationException( componentId.getComponentClassName() + " has no persistent id property" );
 - }
 - //tuplizers
 - XProperty property = inferredData.getProperty();
 - setupComponentTuplizer( property, componentId );
 - }
 - else {
 - //TODO I think this branch is never used. Remove.
 - for ( Ejb3Column column : columns ) {
 - column.forceNotNull(); //this is an id
 - }
 - SimpleValueBinder value = new SimpleValueBinder();
 - value.setPropertyName( propertyName );
 - value.setReturnedClassName( inferredData.getTypeName() );
 - value.setColumns( columns );
 - value.setPersistentClassName( persistentClassName );
 - value.setMappings( mappings );
 - value.setType( inferredData.getProperty(), inferredData.getClassOrElement() );
 - id = value.make();
 - }
 - rootClass.setIdentifier( id );
 - BinderHelper.makeIdGenerator( id, generatorType, generatorName, mappings, localGenerators );
 - if ( isEmbedded ) {
 - rootClass.setEmbeddedIdentifier( inferredData.getPropertyClass() == null );
 - }
 - else {
 - PropertyBinder binder = new PropertyBinder();
 - binder.setName( propertyName );
 - binder.setValue( id );
 - binder.setAccessType( inferredData.getDefaultAccess() );
 - binder.setProperty( inferredData.getProperty() );
 - Property prop = binder.makeProperty();
 - rootClass.setIdentifierProperty( prop );
 - //if the id property is on a superclass, update the metamodel
 - final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
 - inferredData.getDeclaringClass(),
 - inheritanceStatePerClass,
 - mappings
 - );
 - if ( superclass != null ) {
 - superclass.setDeclaredIdentifierProperty( prop );
 - }
 - else {
 - //we know the property is on the actual entity
 - rootClass.setDeclaredIdentifierProperty( prop );
 - }
 - }
 - }
 - private static PropertyData getUniqueIdPropertyFromBaseClass(
 - PropertyData inferredData,
 - PropertyData baseInferredData,
 - AccessType propertyAccessor,
 - Mappings mappings) {
 - List<PropertyData> baseClassElements = new ArrayList<PropertyData>();
 - XClass baseReturnedClassOrElement = baseInferredData.getClassOrElement();
 - PropertyContainer propContainer = new PropertyContainer(
 - baseReturnedClassOrElement, inferredData.getPropertyClass()
 - );
 - addElementsOfClass( baseClassElements, propertyAccessor, propContainer, mappings );
 - //Id properties are on top and there is only one
 - return baseClassElements.get( 0 );
 - }
 - private static void setupComponentTuplizer(XProperty property, Component component) {
 - if ( property == null ) {
 - return;
 - }
 - if ( property.isAnnotationPresent( Tuplizers.class ) ) {
 - for ( Tuplizer tuplizer : property.getAnnotation( Tuplizers.class ).value() ) {
 - EntityMode mode = EntityMode.parse( tuplizer.entityMode() );
 - component.addTuplizer( mode, tuplizer.impl().getName() );
 - }
 - }
 - if ( property.isAnnotationPresent( Tuplizer.class ) ) {
 - Tuplizer tuplizer = property.getAnnotation( Tuplizer.class );
 - EntityMode mode = EntityMode.parse( tuplizer.entityMode() );
 - component.addTuplizer( mode, tuplizer.impl().getName() );
 - }
 - }
 - private static void bindManyToOne(
 - String cascadeStrategy,
 - Ejb3JoinColumn[] columns,
 - boolean optional,
 - boolean ignoreNotFound,
 - boolean cascadeOnDelete,
 - XClass targetEntity,
 - PropertyHolder propertyHolder,
 - PropertyData inferredData,
 - boolean unique,
 - boolean isIdentifierMapper,
 - boolean inSecondPass,
 - PropertyBinder propertyBinder,
 - Mappings mappings) {
 - //All FK columns should be in the same table
 - org.hibernate.mapping.ManyToOne value = new org.hibernate.mapping.ManyToOne( mappings, columns[0].getTable() );
 - // This is a @OneToOne mapped to a physical o.h.mapping.ManyToOne
 - if ( unique ) {
 - value.markAsLogicalOneToOne();
 - }
 - value.setReferencedEntityName( ToOneBinder.getReferenceEntityName( inferredData, targetEntity, mappings ) );
 - final XProperty property = inferredData.getProperty();
 - defineFetchingStrategy( value, property );
 - //value.setFetchMode( fetchMode );
 - value.setIgnoreNotFound( ignoreNotFound );
 - value.setCascadeDeleteEnabled( cascadeOnDelete );
 - //value.setLazy( fetchMode != FetchMode.JOIN );
 - if ( !optional ) {
 - for ( Ejb3JoinColumn column : columns ) {
 - column.setNullable( false );
 - }
 - }
 - if ( property.isAnnotationPresent( MapsId.class ) ) {
 - //read only
 - for ( Ejb3JoinColumn column : columns ) {
 - column.setInsertable( false );
 - column.setUpdatable( false );
 - }
 - }
 - //Make sure that JPA1 key-many-to-one columns are read only tooj
 - boolean hasSpecjManyToOne=false;
 - if ( mappings.isSpecjProprietarySyntaxEnabled() ) {
 - String columnName = "";
 - for ( XProperty prop : inferredData.getDeclaringClass()
 - .getDeclaredProperties( AccessType.FIELD.getType() ) ) {
 - if ( prop.isAnnotationPresent( Id.class ) && prop.isAnnotationPresent( Column.class ) ) {
 - columnName = prop.getAnnotation( Column.class ).name();
 - }
 - final JoinColumn joinColumn = property.getAnnotation( JoinColumn.class );
 - if ( property.isAnnotationPresent( ManyToOne.class ) && joinColumn != null
 - && ! BinderHelper.isEmptyAnnotationValue( joinColumn.name() )
 - && joinColumn.name().equals( columnName )
 - && !property.isAnnotationPresent( MapsId.class ) ) {
 - hasSpecjManyToOne = true;
 - for ( Ejb3JoinColumn column : columns ) {
 - column.setInsertable( false );
 - column.setUpdatable( false );
 - }
 - }
 - }
 - }
 - value.setTypeName( inferredData.getClassOrElementName() );
 - final String propertyName = inferredData.getPropertyName();
 - value.setTypeUsingReflection( propertyHolder.getClassName(), propertyName );
 - ForeignKey fk = property.getAnnotation( ForeignKey.class );
 - String fkName = fk != null ?
 - fk.name() :
 - "";
 - if ( !BinderHelper.isEmptyAnnotationValue( fkName ) ) {
 - value.setForeignKeyName( fkName );
 - }
 - String path = propertyHolder.getPath() + "." + propertyName;
 - FkSecondPass secondPass = new ToOneFkSecondPass(
 - value, columns,
 - !optional && unique, //cannot have nullable and unique on certain DBs like Derby
 - propertyHolder.getEntityOwnerClassName(),
 - path, mappings
 - );
 - if ( inSecondPass ) {
 - secondPass.doSecondPass( mappings.getClasses() );
 - }
 - else {
 - mappings.addSecondPass(
 - secondPass
 - );
 - }
 - Ejb3Column.checkPropertyConsistency( columns, propertyHolder.getEntityName() + propertyName );
 - //PropertyBinder binder = new PropertyBinder();
 - propertyBinder.setName( propertyName );
 - propertyBinder.setValue( value );
 - //binder.setCascade(cascadeStrategy);
 - if ( isIdentifierMapper ) {
 - propertyBinder.setInsertable( false );
 - propertyBinder.setUpdatable( false );
 - }
 - else if (hasSpecjManyToOne) {
 - propertyBinder.setInsertable( false );
 - propertyBinder.setUpdatable( false );
 - }
 - else {
 - propertyBinder.setInsertable( columns[0].isInsertable() );
 - propertyBinder.setUpdatable( columns[0].isUpdatable() );
 - }
 - propertyBinder.setColumns( columns );
 - propertyBinder.setAccessType( inferredData.getDefaultAccess() );
 - propertyBinder.setCascade( cascadeStrategy );
 - propertyBinder.setProperty( property );
 - propertyBinder.setXToMany( true );
 - propertyBinder.makePropertyAndBind();
 - }
 - protected static void defineFetchingStrategy(ToOne toOne, XProperty property) {
 - LazyToOne lazy = property.getAnnotation( LazyToOne.class );
 - Fetch fetch = property.getAnnotation( Fetch.class );
 - ManyToOne manyToOne = property.getAnnotation( ManyToOne.class );
 - OneToOne oneToOne = property.getAnnotation( OneToOne.class );
 - FetchType fetchType;
 - if ( manyToOne != null ) {
 - fetchType = manyToOne.fetch();
 - }
 - else if ( oneToOne != null ) {
 - fetchType = oneToOne.fetch();
 - }
 - else {
 - throw new AssertionFailure(
 - "Define fetch strategy on a property not annotated with @OneToMany nor @OneToOne"
 - );
 - }
 - if ( lazy != null ) {
 - toOne.setLazy( !( lazy.value() == LazyToOneOption.FALSE ) );
 - toOne.setUnwrapProxy( ( lazy.value() == LazyToOneOption.NO_PROXY ) );
 - }
 - else {
 - toOne.setLazy( fetchType == FetchType.LAZY );
 - toOne.setUnwrapProxy( false );
 - }
 - if ( fetch != null ) {
 - if ( fetch.value() == org.hibernate.annotations.FetchMode.JOIN ) {
 - toOne.setFetchMode( FetchMode.JOIN );
 - toOne.setLazy( false );
 - toOne.setUnwrapProxy( false );
 - }
 - else if ( fetch.value() == org.hibernate.annotations.FetchMode.SELECT ) {
 - toOne.setFetchMode( FetchMode.SELECT );
 - }
 - else if ( fetch.value() == org.hibernate.annotations.FetchMode.SUBSELECT ) {
 - throw new AnnotationException( "Use of FetchMode.SUBSELECT not allowed on ToOne associations" );
 - }
 - else {
 - throw new AssertionFailure( "Unknown FetchMode: " + fetch.value() );
 - }
 - }
 - else {
 - toOne.setFetchMode( getFetchMode( fetchType ) );
 - }
 - }
 - private static void bindOneToOne(
 - String cascadeStrategy,
 - Ejb3JoinColumn[] joinColumns,
 - boolean optional,
 - FetchMode fetchMode,
 - boolean ignoreNotFound,
 - boolean cascadeOnDelete,
 - XClass targetEntity,
 - PropertyHolder propertyHolder,
 - PropertyData inferredData, String mappedBy,
 - boolean trueOneToOne,
 - boolean isIdentifierMapper,
 - boolean inSecondPass,
 - PropertyBinder propertyBinder,
 - Mappings mappings) {
 - //column.getTable() => persistentClass.getTable()
 - final String propertyName = inferredData.getPropertyName();
 - log.trace( "Fetching {} with {}", propertyName, fetchMode );
 - boolean mapToPK = true;
 - if ( !trueOneToOne ) {
 - //try to find a hidden true one to one (FK == PK columns)
 - KeyValue identifier = propertyHolder.getIdentifier();
 - if ( identifier == null ) {
 - //this is a @OneToOne in a @EmbeddedId (the persistentClass.identifier is not set yet, it's being built)
 - //by definition the PK cannot refers to itself so it cannot map to itself
 - mapToPK = false;
 - }
 - else {
 - Iterator idColumns = identifier.getColumnIterator();
 - List<String> idColumnNames = new ArrayList<String>();
 - org.hibernate.mapping.Column currentColumn;
 - if ( identifier.getColumnSpan() != joinColumns.length ) {
 - mapToPK = false;
 - }
 - else {
 - while ( idColumns.hasNext() ) {
 - currentColumn = ( org.hibernate.mapping.Column ) idColumns.next();
 - idColumnNames.add( currentColumn.getName() );
 - }
 - for ( Ejb3JoinColumn col : joinColumns ) {
 - if ( !idColumnNames.contains( col.getMappingColumn().getName() ) ) {
 - mapToPK = false;
 - break;
 - }
 - }
 - }
 - }
 - }
 - if ( trueOneToOne || mapToPK || !BinderHelper.isEmptyAnnotationValue( mappedBy ) ) {
 - //is a true one-to-one
 - //FIXME referencedColumnName ignored => ordering may fail.
 - OneToOneSecondPass secondPass = new OneToOneSecondPass(
 - mappedBy,
 - propertyHolder.getEntityName(),
 - propertyName,
 - propertyHolder, inferredData, targetEntity, ignoreNotFound, cascadeOnDelete,
 - optional, cascadeStrategy, joinColumns, mappings
 - );
 - if ( inSecondPass ) {
 - secondPass.doSecondPass( mappings.getClasses() );
 - }
 - else {
 - mappings.addSecondPass(
 - secondPass, BinderHelper.isEmptyAnnotationValue( mappedBy )
 - );
 - }
 - }
 - else {
 - //has a FK on the table
 - bindManyToOne(
 - cascadeStrategy, joinColumns, optional, ignoreNotFound, cascadeOnDelete,
 - targetEntity,
 - propertyHolder, inferredData, true, isIdentifierMapper, inSecondPass,
 - propertyBinder, mappings
 - );
 - }
 - }
 - private static void bindAny(
 - String cascadeStrategy,
 - Ejb3JoinColumn[] columns,
 - boolean cascadeOnDelete,
 - Nullability nullability,
 - PropertyHolder propertyHolder,
 - PropertyData inferredData,
 - EntityBinder entityBinder,
 - boolean isIdentifierMapper,
 - Mappings mappings) {
 - org.hibernate.annotations.Any anyAnn = inferredData.getProperty()
 - .getAnnotation( org.hibernate.annotations.Any.class );
 - if ( anyAnn == null ) {
 - throw new AssertionFailure(
 - "Missing @Any annotation: "
 - + BinderHelper.getPath( propertyHolder, inferredData )
 - );
 - }
 - Any value = BinderHelper.buildAnyValue(
 - anyAnn.metaDef(), columns, anyAnn.metaColumn(), inferredData,
 - cascadeOnDelete, nullability, propertyHolder, entityBinder, anyAnn.optional(), mappings
 - );
 - PropertyBinder binder = new PropertyBinder();
 - binder.setName( inferredData.getPropertyName() );
 - binder.setValue( value );
 - binder.setLazy( anyAnn.fetch() == FetchType.LAZY );
 - //binder.setCascade(cascadeStrategy);
 - if ( isIdentifierMapper ) {
 - binder.setInsertable( false );
 - binder.setUpdatable( false );
 - }
 - else {
 - binder.setInsertable( columns[0].isInsertable() );
 - binder.setUpdatable( columns[0].isUpdatable() );
 - }
 - binder.setAccessType( inferredData.getDefaultAccess() );
 - binder.setCascade( cascadeStrategy );
 - Property prop = binder.makeProperty();
 - //composite FK columns are in the same table so its OK
 - propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() );
 - }
 - private static String generatorType(GenerationType generatorEnum, Mappings mappings) {
 - boolean useNewGeneratorMappings = mappings.useNewGeneratorMappings();
 - switch ( generatorEnum ) {
 - case IDENTITY:
 - return "identity";
 - case AUTO:
 - return useNewGeneratorMappings
 - ? org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName()
 - : "native";
 - case TABLE:
 - return useNewGeneratorMappings
 - ? org.hibernate.id.enhanced.TableGenerator.class.getName()
 - : MultipleHiLoPerTableGenerator.class.getName();
 - case SEQUENCE:
 - return useNewGeneratorMappings
 - ? org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName()
 - : "seqhilo";
 - }
 - throw new AssertionFailure( "Unknown GeneratorType: " + generatorEnum );
 - }
 - private static EnumSet<CascadeType> convertToHibernateCascadeType(javax.persistence.CascadeType[] ejbCascades) {
 - EnumSet<CascadeType> hibernateCascadeSet = EnumSet.noneOf( CascadeType.class );
 - if ( ejbCascades != null && ejbCascades.length > 0 ) {
 - for ( javax.persistence.CascadeType cascade : ejbCascades ) {
 - switch ( cascade ) {
 - case ALL:
 - hibernateCascadeSet.add( CascadeType.ALL );
 - break;
 - case PERSIST:
 - hibernateCascadeSet.add( CascadeType.PERSIST );
 - break;
 - case MERGE:
 - hibernateCascadeSet.add( CascadeType.MERGE );
 - break;
 - case REMOVE:
 - hibernateCascadeSet.add( CascadeType.REMOVE );
 - break;
 - case REFRESH:
 - hibernateCascadeSet.add( CascadeType.REFRESH );
 - break;
 - case DETACH:
 - hibernateCascadeSet.add( CascadeType.DETACH );
 - break;
 - }
 - }
 - }
 - return hibernateCascadeSet;
 - }
 - private static String getCascadeStrategy(
 - javax.persistence.CascadeType[] ejbCascades,
 - Cascade hibernateCascadeAnnotation,
 - boolean orphanRemoval,
 - boolean forcePersist) {
 - EnumSet<CascadeType> hibernateCascadeSet = convertToHibernateCascadeType( ejbCascades );
 - CascadeType[] hibernateCascades = hibernateCascadeAnnotation == null ?
 - null :
 - hibernateCascadeAnnotation.value();
 - if ( hibernateCascades != null && hibernateCascades.length > 0 ) {
 - hibernateCascadeSet.addAll( Arrays.asList( hibernateCascades ) );
 - }
 - if ( orphanRemoval ) {
 - hibernateCascadeSet.add( CascadeType.DELETE_ORPHAN );
 - hibernateCascadeSet.add( CascadeType.REMOVE );
 - }
 - if ( forcePersist ) {
 - hibernateCascadeSet.add( CascadeType.PERSIST );
 - }
 - StringBuilder cascade = new StringBuilder();
 - for ( CascadeType aHibernateCascadeSet : hibernateCascadeSet ) {
 - switch ( aHibernateCascadeSet ) {
 - case ALL:
 - cascade.append( "," ).append( "all" );
 - break;
 - case SAVE_UPDATE:
 - cascade.append( "," ).append( "save-update" );
 - break;
 - case PERSIST:
 - cascade.append( "," ).append( "persist" );
 - break;
 - case MERGE:
 - cascade.append( "," ).append( "merge" );
 - break;
 - case LOCK:
 - cascade.append( "," ).append( "lock" );
 - break;
 - case REFRESH:
 - cascade.append( "," ).append( "refresh" );
 - break;
 - case REPLICATE:
 - cascade.append( "," ).append( "replicate" );
 - break;
 - case EVICT:
 - case DETACH:
 - cascade.append( "," ).append( "evict" );
 - break;
 - case DELETE:
 - cascade.append( "," ).append( "delete" );
 - break;
 - case DELETE_ORPHAN:
 - cascade.append( "," ).append( "delete-orphan" );
 - break;
 - case REMOVE:
 - cascade.append( "," ).append( "delete" );
 - break;
 - }
 - }
 - return cascade.length() > 0 ?
 - cascade.substring( 1 ) :
 - "none";
 - }
 - public static FetchMode getFetchMode(FetchType fetch) {
 - if ( fetch == FetchType.EAGER ) {
 - return FetchMode.JOIN;
 - }
 - else {
 - return FetchMode.SELECT;
 - }
 - }
 - private static HashMap<String, IdGenerator> buildLocalGenerators(XAnnotatedElement annElt, Mappings mappings) {
 - HashMap<String, IdGenerator> generators = new HashMap<String, IdGenerator>();
 - TableGenerator tabGen = annElt.getAnnotation( TableGenerator.class );
 - SequenceGenerator seqGen = annElt.getAnnotation( SequenceGenerator.class );
 - GenericGenerator genGen = annElt.getAnnotation( GenericGenerator.class );
 - if ( tabGen != null ) {
 - IdGenerator idGen = buildIdGenerator( tabGen, mappings );
 - generators.put( idGen.getName(), idGen );
 - }
 - if ( seqGen != null ) {
 - IdGenerator idGen = buildIdGenerator( seqGen, mappings );
 - generators.put( idGen.getName(), idGen );
 - }
 - if ( genGen != null ) {
 - IdGenerator idGen = buildIdGenerator( genGen, mappings );
 - generators.put( idGen.getName(), idGen );
 - }
 - return generators;
 - }
 - public static boolean isDefault(XClass clazz, Mappings mappings) {
 - return mappings.getReflectionManager().equals( clazz, void.class );
 - }
 - /**
 - * For the mapped entities build some temporary data-structure containing information about the
 - * inheritance status of a class.
 - *
 - * @param orderedClasses Order list of all annotated entities and their mapped superclasses
 - *
 - * @return A map of {@code InheritanceState}s keyed against their {@code XClass}.
 - */
 - public static Map<XClass, InheritanceState> buildInheritanceStates(
 - List<XClass> orderedClasses,
 - Mappings mappings) {
 - ReflectionManager reflectionManager = mappings.getReflectionManager();
 - Map<XClass, InheritanceState> inheritanceStatePerClass = new HashMap<XClass, InheritanceState>(
 - orderedClasses.size()
 - );
 - for ( XClass clazz : orderedClasses ) {
 - InheritanceState superclassState = InheritanceState.getSuperclassInheritanceState(
 - clazz, inheritanceStatePerClass
 - );
 - InheritanceState state = new InheritanceState( clazz, inheritanceStatePerClass, mappings );
 - if ( superclassState != null ) {
 - //the classes are ordered thus preventing an NPE
 - //FIXME if an entity has subclasses annotated @MappedSperclass wo sub @Entity this is wrong
 - superclassState.setHasSiblings( true );
 - InheritanceState superEntityState = InheritanceState.getInheritanceStateOfSuperEntity(
 - clazz, inheritanceStatePerClass
 - );
 - state.setHasParents( superEntityState != null );
 - final boolean nonDefault = state.getType() != null && !InheritanceType.SINGLE_TABLE
 - .equals( state.getType() );
 - if ( superclassState.getType() != null ) {
 - final boolean mixingStrategy = state.getType() != null && !state.getType()
 - .equals( superclassState.getType() );
 - if ( nonDefault && mixingStrategy ) {
 - log.warn(
 - "Mixing inheritance strategy in a entity hierarchy is not allowed, ignoring sub strategy in: {}",
 - clazz.getName()
 - );
 - }
 - state.setType( superclassState.getType() );
 - }
 - }
 - inheritanceStatePerClass.put( clazz, state );
 - }
 - return inheritanceStatePerClass;
 - }
 - private static boolean hasAnnotationsOnIdClass(XClass idClass) {
 - // if(idClass.getAnnotation(Embeddable.class) != null)
 - // return true;
 - List<XProperty> properties = idClass.getDeclaredProperties( XClass.ACCESS_FIELD );
 - for ( XProperty property : properties ) {
 - if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent( OneToMany.class ) ||
 - property.isAnnotationPresent( ManyToOne.class ) || property.isAnnotationPresent( Id.class ) ||
 - property.isAnnotationPresent( GeneratedValue.class ) || property.isAnnotationPresent( OneToOne.class ) ||
 - property.isAnnotationPresent( ManyToMany.class )
 - ) {
 - return true;
 - }
 - }
 - List<XMethod> methods = idClass.getDeclaredMethods();
 - for ( XMethod method : methods ) {
 - if ( method.isAnnotationPresent( Column.class ) || method.isAnnotationPresent( OneToMany.class ) ||
 - method.isAnnotationPresent( ManyToOne.class ) || method.isAnnotationPresent( Id.class ) ||
 - method.isAnnotationPresent( GeneratedValue.class ) || method.isAnnotationPresent( OneToOne.class ) ||
 - method.isAnnotationPresent( ManyToMany.class )
 - ) {
 - return true;
 - }
 - }
 - return false;
 - }
 - }
 
                    
                
                
            
        
浙公网安备 33010602011771号