public void addPair(GenerationStrategyPair generationStrategyPair) { add(generationStrategyPair.getInMemoryStrategy()); add(generationStrategyPair.getInDatabaseStrategy()); }
public EntityMetamodel( PersistentClass persistentClass, AbstractEntityPersister persister, SessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; this.persister = persister; name = persistentClass.getEntityName(); rootName = persistentClass.getRootClass().getEntityName(); entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne(name); identifierAttribute = PropertyFactory.buildIdentifierAttribute( persistentClass, sessionFactory.getIdentifierGenerator(rootName)); versioned = persistentClass.isVersioned(); instrumentationMetadata = persistentClass.hasPojoRepresentation() ? Environment.getBytecodeProvider() .getEntityInstrumentationMetadata(persistentClass.getMappedClass()) : new NonPojoInstrumentationMetadata(persistentClass.getEntityName()); boolean hasLazy = false; propertySpan = persistentClass.getPropertyClosureSpan(); properties = new NonIdentifierAttribute[propertySpan]; List<Integer> naturalIdNumbers = new ArrayList<Integer>(); // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ propertyNames = new String[propertySpan]; propertyTypes = new Type[propertySpan]; propertyUpdateability = new boolean[propertySpan]; propertyInsertability = new boolean[propertySpan]; nonlazyPropertyUpdateability = new boolean[propertySpan]; propertyCheckability = new boolean[propertySpan]; propertyNullability = new boolean[propertySpan]; propertyVersionability = new boolean[propertySpan]; propertyLaziness = new boolean[propertySpan]; cascadeStyles = new CascadeStyle[propertySpan]; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // generated value strategies // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this.inMemoryValueGenerationStrategies = new InMemoryValueGenerationStrategy[propertySpan]; this.inDatabaseValueGenerationStrategies = new InDatabaseValueGenerationStrategy[propertySpan]; boolean foundPreInsertGeneratedValues = false; boolean foundPreUpdateGeneratedValues = false; boolean foundPostInsertGeneratedValues = false; boolean foundPostUpdateGeneratedValues = false; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Iterator iter = persistentClass.getPropertyClosureIterator(); int i = 0; int tempVersionProperty = NO_VERSION_INDX; boolean foundCascade = false; boolean foundCollection = false; boolean foundMutable = false; boolean foundNonIdentifierPropertyNamedId = false; boolean foundInsertGeneratedValue = false; boolean foundUpdateGeneratedValue = false; boolean foundUpdateableNaturalIdProperty = false; while (iter.hasNext()) { Property prop = (Property) iter.next(); if (prop == persistentClass.getVersion()) { tempVersionProperty = i; properties[i] = PropertyFactory.buildVersionProperty( persister, sessionFactory, i, prop, instrumentationMetadata.isInstrumented()); } else { properties[i] = PropertyFactory.buildEntityBasedAttribute( persister, sessionFactory, i, prop, instrumentationMetadata.isInstrumented()); } if (prop.isNaturalIdentifier()) { naturalIdNumbers.add(i); if (prop.isUpdateable()) { foundUpdateableNaturalIdProperty = true; } } if ("id".equals(prop.getName())) { foundNonIdentifierPropertyNamedId = true; } // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ boolean lazy = prop.isLazy() && instrumentationMetadata.isInstrumented(); if (lazy) hasLazy = true; propertyLaziness[i] = lazy; propertyNames[i] = properties[i].getName(); propertyTypes[i] = properties[i].getType(); propertyNullability[i] = properties[i].isNullable(); propertyUpdateability[i] = properties[i].isUpdateable(); propertyInsertability[i] = properties[i].isInsertable(); propertyVersionability[i] = properties[i].isVersionable(); nonlazyPropertyUpdateability[i] = properties[i].isUpdateable() && !lazy; propertyCheckability[i] = propertyUpdateability[i] || (propertyTypes[i].isAssociationType() && ((AssociationType) propertyTypes[i]).isAlwaysDirtyChecked()); cascadeStyles[i] = properties[i].getCascadeStyle(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // generated value strategies // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GenerationStrategyPair pair = buildGenerationStrategyPair(sessionFactory, prop); inMemoryValueGenerationStrategies[i] = pair.getInMemoryStrategy(); inDatabaseValueGenerationStrategies[i] = pair.getInDatabaseStrategy(); if (pair.getInMemoryStrategy() != null) { final GenerationTiming timing = pair.getInMemoryStrategy().getGenerationTiming(); if (timing != GenerationTiming.NEVER) { final ValueGenerator generator = pair.getInMemoryStrategy().getValueGenerator(); if (generator != null) { // we have some level of generation indicated if (timing == GenerationTiming.INSERT) { foundPreInsertGeneratedValues = true; } else if (timing == GenerationTiming.ALWAYS) { foundPreInsertGeneratedValues = true; foundPreUpdateGeneratedValues = true; } } } } if (pair.getInDatabaseStrategy() != null) { final GenerationTiming timing = pair.getInDatabaseStrategy().getGenerationTiming(); if (timing == GenerationTiming.INSERT) { foundPostInsertGeneratedValues = true; } else if (timing == GenerationTiming.ALWAYS) { foundPostInsertGeneratedValues = true; foundPostUpdateGeneratedValues = true; } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (properties[i].isLazy()) { hasLazy = true; } if (properties[i].getCascadeStyle() != CascadeStyles.NONE) { foundCascade = true; } if (indicatesCollection(properties[i].getType())) { foundCollection = true; } if (propertyTypes[i].isMutable() && propertyCheckability[i]) { foundMutable = true; } mapPropertyToIndex(prop, i); i++; } if (naturalIdNumbers.size() == 0) { naturalIdPropertyNumbers = null; hasImmutableNaturalId = false; hasCacheableNaturalId = false; } else { naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers); hasImmutableNaturalId = !foundUpdateableNaturalIdProperty; hasCacheableNaturalId = persistentClass.getNaturalIdCacheRegionName() != null; } this.hasPreInsertGeneratedValues = foundPreInsertGeneratedValues; this.hasPreUpdateGeneratedValues = foundPreUpdateGeneratedValues; this.hasInsertGeneratedValues = foundPostInsertGeneratedValues; this.hasUpdateGeneratedValues = foundPostUpdateGeneratedValues; hasCascades = foundCascade; hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId; versionPropertyIndex = tempVersionProperty; hasLazyProperties = hasLazy; if (hasLazyProperties) LOG.lazyPropertyFetchingAvailable(name); lazy = persistentClass.isLazy() && ( // TODO: this disables laziness even in non-pojo entity modes: !persistentClass.hasPojoRepresentation() || !ReflectHelper.isFinalClass(persistentClass.getProxyInterface())); mutable = persistentClass.isMutable(); if (persistentClass.isAbstract() == null) { // legacy behavior (with no abstract attribute specified) isAbstract = persistentClass.hasPojoRepresentation() && ReflectHelper.isAbstractClass(persistentClass.getMappedClass()); } else { isAbstract = persistentClass.isAbstract().booleanValue(); if (!isAbstract && persistentClass.hasPojoRepresentation() && ReflectHelper.isAbstractClass(persistentClass.getMappedClass())) { LOG.entityMappedAsNonAbstract(name); } } selectBeforeUpdate = persistentClass.hasSelectBeforeUpdate(); dynamicUpdate = persistentClass.useDynamicUpdate(); dynamicInsert = persistentClass.useDynamicInsert(); polymorphic = persistentClass.isPolymorphic(); explicitPolymorphism = persistentClass.isExplicitPolymorphism(); inherited = persistentClass.isInherited(); superclass = inherited ? persistentClass.getSuperclass().getEntityName() : null; hasSubclasses = persistentClass.hasSubclasses(); optimisticLockStyle = persistentClass.getOptimisticLockStyle(); final boolean isAllOrDirty = optimisticLockStyle == OptimisticLockStyle.ALL || optimisticLockStyle == OptimisticLockStyle.DIRTY; if (isAllOrDirty && !dynamicUpdate) { throw new MappingException( "optimistic-lock=all|dirty requires dynamic-update=\"true\": " + name); } if (versionPropertyIndex != NO_VERSION_INDX && isAllOrDirty) { throw new MappingException( "version and optimistic-lock=all|dirty are not a valid combination : " + name); } hasCollections = foundCollection; hasMutableProperties = foundMutable; iter = persistentClass.getSubclassIterator(); while (iter.hasNext()) { subclassEntityNames.add(((PersistentClass) iter.next()).getEntityName()); } subclassEntityNames.add(name); if (persistentClass.hasPojoRepresentation()) { entityNameByInheritenceClassMap.put( persistentClass.getMappedClass(), persistentClass.getEntityName()); iter = persistentClass.getSubclassIterator(); while (iter.hasNext()) { final PersistentClass pc = (PersistentClass) iter.next(); entityNameByInheritenceClassMap.put(pc.getMappedClass(), pc.getEntityName()); } } entityMode = persistentClass.hasPojoRepresentation() ? EntityMode.POJO : EntityMode.MAP; final EntityTuplizerFactory entityTuplizerFactory = sessionFactory.getSettings().getEntityTuplizerFactory(); final String tuplizerClassName = persistentClass.getTuplizerImplClassName(entityMode); if (tuplizerClassName == null) { entityTuplizer = entityTuplizerFactory.constructDefaultTuplizer(entityMode, this, persistentClass); } else { entityTuplizer = entityTuplizerFactory.constructTuplizer(tuplizerClassName, this, persistentClass); } }