下面列出了怎么用org.hibernate.mapping.RootClass的API类实例代码及写法,或者点击链接到github查看源代码。
private static PersistentClass makePersistentClass(
InheritanceState inheritanceState,
PersistentClass superEntity,
MetadataBuildingContext metadataBuildingContext) {
//we now know what kind of persistent entity it is
if ( !inheritanceState.hasParents() ) {
return new RootClass( metadataBuildingContext );
}
else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
return new SingleTableSubclass( superEntity, metadataBuildingContext );
}
else if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) ) {
return new JoinedSubclass( superEntity, metadataBuildingContext );
}
else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
return new UnionSubclass( superEntity, metadataBuildingContext );
}
else {
throw new AssertionFailure( "Unknown inheritance type: " + inheritanceState.getType() );
}
}
private static void bindDiscriminatorColumnToRootPersistentClass(
RootClass rootClass,
Ejb3DiscriminatorColumn discriminatorColumn,
Map<String, Join> secondaryTables,
PropertyHolder propertyHolder,
MetadataBuildingContext context) {
if ( rootClass.getDiscriminator() == null ) {
if ( discriminatorColumn == null ) {
throw new AssertionFailure( "discriminator column should have been built" );
}
discriminatorColumn.setJoins( secondaryTables );
discriminatorColumn.setPropertyHolder( propertyHolder );
SimpleValue discriminatorColumnBinding = new SimpleValue( context, rootClass.getTable() );
rootClass.setDiscriminator( discriminatorColumnBinding );
discriminatorColumn.linkWithValue( discriminatorColumnBinding );
discriminatorColumnBinding.setTypeName( discriminatorColumn.getDiscriminatorTypeName() );
rootClass.setPolymorphic( true );
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Setting discriminator for entity {0}", rootClass.getEntityName() );
}
}
}
@Override
public void addEntityBinding(PersistentClass persistentClass) throws DuplicateMappingException {
final String entityName = persistentClass.getEntityName();
if ( entityBindingMap.containsKey( entityName ) ) {
throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, entityName );
}
entityBindingMap.put( entityName, persistentClass );
final AccessType accessType = AccessType.fromExternalName( persistentClass.getCacheConcurrencyStrategy() );
if ( accessType != null ) {
if ( persistentClass.isCached() ) {
locateCacheRegionConfigBuilder( persistentClass.getRootClass().getCacheRegionName() ).addEntityConfig(
persistentClass,
accessType
);
}
if ( persistentClass.hasNaturalId() && persistentClass instanceof RootClass && persistentClass.getNaturalIdCacheRegionName() != null ) {
locateCacheRegionConfigBuilder( persistentClass.getNaturalIdCacheRegionName() ).addNaturalIdConfig(
(RootClass) persistentClass,
accessType
);
}
}
}
public boolean needsIdTable(PersistentClass entityBinding) {
// need id table if the entity has secondary tables (joins)
if ( entityBinding.getJoinClosureSpan() > 0 ) {
return true;
}
// need an id table if the entity is part of either a JOINED or UNION inheritance
// hierarchy. We do not allow inheritance strategy mixing, so work on that assumption
// here...
final RootClass rootEntityBinding = entityBinding.getRootClass();
final Iterator itr = rootEntityBinding.getSubclassIterator();
if ( itr.hasNext() ) {
final Subclass subclassEntityBinding = (Subclass) itr.next();
if ( subclassEntityBinding instanceof JoinedSubclass || subclassEntityBinding instanceof UnionSubclass ) {
return true;
}
}
return false;
}
private static void bindDiscriminatorProperty(Table table, RootClass entity, Element subnode,
Mappings mappings) {
SimpleValue discrim = new SimpleValue( table );
entity.setDiscriminator( discrim );
bindSimpleValue(
subnode,
discrim,
false,
RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME,
mappings
);
if ( !discrim.isTypeSpecified() ) {
discrim.setTypeName( "string" );
// ( (Column) discrim.getColumnIterator().next() ).setType(type);
}
entity.setPolymorphic( true );
if ( "true".equals( subnode.attributeValue( "force" ) ) )
entity.setForceDiscriminator( true );
if ( "false".equals( subnode.attributeValue( "insert" ) ) )
entity.setDiscriminatorInsertable( false );
}
public void testProperCallbacks() {
ValueVisitor vv = new ValueVisitorValidator();
new Any(new Table()).accept(vv);
new Array(new RootClass()).accept(vv);
new Bag(new RootClass()).accept(vv);
new Component(new RootClass()).accept(vv);
new DependantValue(null,null).accept(vv);
new IdentifierBag(null).accept(vv);
new List(null).accept(vv);
new ManyToOne(null).accept(vv);
new Map(null).accept(vv);
new OneToMany(null).accept(vv);
new OneToOne(null, new RootClass() ).accept(vv);
new PrimitiveArray(null).accept(vv);
new Set(null).accept(vv);
new SimpleValue().accept(vv);
}
/**
* 构造Hibernate的乐观锁
*/
private void handleVersion(Property prop, PersistentClass pclazz) {
if (!(pclazz instanceof RootClass)) {
throw new AnnotationException(
"Unable to define/override @Version on a subclass: "
+ pclazz.getEntityName());
}
RootClass root = (RootClass) pclazz;
root.setVersion(prop);
root.setDeclaredVersion(prop);
root.setOptimisticLockStyle(OptimisticLockStyle.VERSION);
}
@SuppressWarnings("UnusedReturnValue")
public Builder addNaturalIdConfig(RootClass rootEntityDescriptor, AccessType accessType) {
if ( naturalIdConfigs == null ) {
naturalIdConfigs = new ArrayList<>();
}
naturalIdConfigs.add( new NaturalIdDataCachingConfigImpl( rootEntityDescriptor, accessType ) );
return this;
}
public NaturalIdDataCachingConfigImpl(
RootClass rootEntityDescriptor,
AccessType accessType) {
super( accessType );
this.rootEntityDescriptor = rootEntityDescriptor;
this.navigableRole = new NavigableRole( rootEntityDescriptor.getEntityName() );
// sucks that we need to do this here. persister does the same "calculation"
this.mutable = hasAnyMutableNaturalIdProps();
}
public void bindEntityHierarchy(EntityHierarchySourceImpl hierarchySource) {
final RootClass rootEntityDescriptor = new RootClass( metadataBuildingContext );
bindRootEntity( hierarchySource, rootEntityDescriptor );
hierarchySource.getRoot()
.getLocalMetadataBuildingContext()
.getMetadataCollector()
.addEntityBinding( rootEntityDescriptor );
switch ( hierarchySource.getHierarchyInheritanceType() ) {
case NO_INHERITANCE: {
// nothing to do
break;
}
case DISCRIMINATED: {
bindDiscriminatorSubclassEntities( hierarchySource.getRoot(), rootEntityDescriptor );
break;
}
case JOINED: {
bindJoinedSubclassEntities( hierarchySource.getRoot(), rootEntityDescriptor );
break;
}
case UNION: {
bindUnionSubclassEntities( hierarchySource.getRoot(), rootEntityDescriptor );
break;
}
}
}
private void finishBindingCompositeIdentifier(
MappingDocument sourceDocument,
RootClass rootEntityDescriptor,
CompositeIdentifierSource identifierSource,
Component cid,
String propertyName) {
if ( propertyName == null ) {
rootEntityDescriptor.setEmbeddedIdentifier( cid.isEmbedded() );
if ( cid.isEmbedded() ) {
// todo : what is the implication of this?
cid.setDynamic( !rootEntityDescriptor.hasPojoRepresentation() );
/*
* Property prop = new Property(); prop.setName("id");
* prop.setPropertyAccessorName("embedded"); prop.setValue(id);
* entity.setIdentifierProperty(prop);
*/
}
}
else {
Property prop = new Property();
prop.setValue( cid );
bindProperty(
sourceDocument,
( (IdentifierSourceAggregatedComposite) identifierSource ).getIdentifierAttributeSource(),
prop
);
rootEntityDescriptor.setIdentifierProperty( prop );
rootEntityDescriptor.setDeclaredIdentifierProperty( prop );
}
makeIdentifier(
sourceDocument,
identifierSource.getIdentifierGeneratorDescriptor(),
null,
cid
);
}
private void processCachingOverrides() {
if ( bootstrapContext.getCacheRegionDefinitions() == null ) {
return;
}
for ( CacheRegionDefinition cacheRegionDefinition : bootstrapContext.getCacheRegionDefinitions() ) {
if ( cacheRegionDefinition.getRegionType() == CacheRegionDefinition.CacheRegionType.ENTITY ) {
final PersistentClass entityBinding = getEntityBinding( cacheRegionDefinition.getRole() );
if ( entityBinding == null ) {
throw new HibernateException(
"Cache override referenced an unknown entity : " + cacheRegionDefinition.getRole()
);
}
if ( !RootClass.class.isInstance( entityBinding ) ) {
throw new HibernateException(
"Cache override referenced a non-root entity : " + cacheRegionDefinition.getRole()
);
}
entityBinding.setCached( true );
( (RootClass) entityBinding ).setCacheRegionName( cacheRegionDefinition.getRegion() );
( (RootClass) entityBinding ).setCacheConcurrencyStrategy( cacheRegionDefinition.getUsage() );
( (RootClass) entityBinding ).setLazyPropertiesCacheable( cacheRegionDefinition.isCacheLazy() );
}
else if ( cacheRegionDefinition.getRegionType() == CacheRegionDefinition.CacheRegionType.COLLECTION ) {
final Collection collectionBinding = getCollectionBinding( cacheRegionDefinition.getRole() );
if ( collectionBinding == null ) {
throw new HibernateException(
"Cache override referenced an unknown collection role : " + cacheRegionDefinition.getRole()
);
}
collectionBinding.setCacheRegionName( cacheRegionDefinition.getRegion() );
collectionBinding.setCacheConcurrencyStrategy( cacheRegionDefinition.getUsage() );
}
}
}
private void processExportableProducers() {
// for now we only handle id generators as ExportableProducers
final Dialect dialect = getDatabase().getJdbcEnvironment().getDialect();
final String defaultCatalog = extractName( getDatabase().getDefaultNamespace().getName().getCatalog(), dialect );
final String defaultSchema = extractName( getDatabase().getDefaultNamespace().getName().getSchema(), dialect );
for ( PersistentClass entityBinding : entityBindingMap.values() ) {
if ( entityBinding.isInherited() ) {
continue;
}
handleIdentifierValueBinding(
entityBinding.getIdentifier(),
dialect,
defaultCatalog,
defaultSchema,
(RootClass) entityBinding
);
}
for ( Collection collection : collectionBindingMap.values() ) {
if ( !IdentifierCollection.class.isInstance( collection ) ) {
continue;
}
handleIdentifierValueBinding(
( (IdentifierCollection) collection ).getIdentifier(),
dialect,
defaultCatalog,
defaultSchema,
null
);
}
}
private void handleIdentifierValueBinding(
KeyValue identifierValueBinding,
Dialect dialect,
String defaultCatalog,
String defaultSchema,
RootClass entityBinding) {
// todo : store this result (back into the entity or into the KeyValue, maybe?)
// This process of instantiating the id-generator is called multiple times.
// It was done this way in the old code too, so no "regression" here; but
// it could be done better
try {
final IdentifierGenerator ig = identifierValueBinding.createIdentifierGenerator(
getIdentifierGeneratorFactory(),
dialect,
defaultCatalog,
defaultSchema,
entityBinding
);
if ( ig instanceof ExportableProducer ) {
( (ExportableProducer) ig ).registerExportables( getDatabase() );
}
}
catch (MappingException e) {
// ignore this for now. The reasoning being "non-reflective" binding as needed
// by tools. We want to hold off requiring classes being present until we
// try to build a SF. Here, just building the Metadata, it is "ok" for an
// exception to occur, the same exception will happen later as we build the SF.
log.debugf( "Ignoring exception thrown when trying to build IdentifierGenerator as part of Metadata building", e );
}
}
private static void bindCompositeId(Element idNode, RootClass entity, Mappings mappings,
java.util.Map inheritedMetas) throws MappingException {
String propertyName = idNode.attributeValue( "name" );
Component id = new Component( entity );
entity.setIdentifier( id );
bindCompositeId( idNode, id, entity, propertyName, mappings, inheritedMetas );
if ( propertyName == null ) {
entity.setEmbeddedIdentifier( id.isEmbedded() );
if ( id.isEmbedded() ) {
// todo : what is the implication of this?
id.setDynamic( !entity.hasPojoRepresentation() );
/*
* Property prop = new Property(); prop.setName("id");
* prop.setPropertyAccessorName("embedded"); prop.setValue(id);
* entity.setIdentifierProperty(prop);
*/
}
}
else {
Property prop = new Property();
prop.setValue( id );
bindProperty( idNode, prop, mappings, inheritedMetas );
entity.setIdentifierProperty( prop );
}
makeIdentifier( idNode, id, mappings );
}
private static void bindVersioningProperty(Table table, Element subnode, Mappings mappings,
String name, RootClass entity, java.util.Map inheritedMetas) {
String propertyName = subnode.attributeValue( "name" );
SimpleValue val = new SimpleValue( table );
bindSimpleValue( subnode, val, false, propertyName, mappings );
if ( !val.isTypeSpecified() ) {
// this is either a <version/> tag with no type attribute,
// or a <timestamp/> tag
if ( "version".equals( name ) ) {
val.setTypeName( "integer" );
}
else {
if ( "db".equals( subnode.attributeValue( "source" ) ) ) {
val.setTypeName( "dbtimestamp" );
}
else {
val.setTypeName( "timestamp" );
}
}
}
Property prop = new Property();
prop.setValue( val );
bindProperty( subnode, prop, mappings, inheritedMetas );
// for version properties marked as being generated, make sure they are "always"
// generated; aka, "insert" is invalid; this is dis-allowed by the DTD,
// but just to make sure...
if ( prop.getGeneration() == PropertyGeneration.INSERT ) {
throw new MappingException( "'generated' attribute cannot be 'insert' for versioning property" );
}
makeVersion( subnode, val );
entity.setVersion( prop );
entity.addProperty( prop );
}
RootClass getRootClassMapping(String clazz) throws MappingException {
try {
return (RootClass) getClassMapping( clazz );
}
catch (ClassCastException cce) {
throw new MappingException( "You may only specify a cache for root <class> mappings" );
}
}
void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region, boolean includeLazy)
throws MappingException {
RootClass rootClass = getRootClassMapping( clazz );
if ( rootClass == null ) {
throw new MappingException( "Cannot cache an unknown entity: " + clazz );
}
rootClass.setCacheConcurrencyStrategy( concurrencyStrategy );
rootClass.setCacheRegionName( region );
rootClass.setLazyPropertiesCacheable( includeLazy );
}
public void testProperCallbacks() {
PersistentClassVisitorValidator vv = new PersistentClassVisitorValidator();
new RootClass().accept(vv);
new Subclass(new RootClass()).accept(vv);
new JoinedSubclass(new RootClass()).accept(vv);
new SingleTableSubclass(new RootClass()).accept(vv);
new UnionSubclass(new RootClass()).accept(vv);
}
/**
* @param accessType Cache access typr.
* @param igniteInstanceName Name of the grid providing caches.
* @return Session factory.
*/
private SessionFactory startHibernate(AccessType accessType, String igniteInstanceName) {
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder();
builder.applySetting("hibernate.connection.url", CONNECTION_URL);
for (Map.Entry<String, String> e : HibernateL2CacheSelfTest.hibernateProperties(igniteInstanceName, accessType.name()).entrySet())
builder.applySetting(e.getKey(), e.getValue());
builder.applySetting(USE_STRUCTURED_CACHE, "true");
builder.applySetting(REGION_CACHE_PROPERTY + ENTITY1_NAME, "cache1");
builder.applySetting(REGION_CACHE_PROPERTY + ENTITY2_NAME, "cache2");
builder.applySetting(REGION_CACHE_PROPERTY + TIMESTAMP_CACHE, TIMESTAMP_CACHE);
builder.applySetting(REGION_CACHE_PROPERTY + QUERY_CACHE, QUERY_CACHE);
MetadataSources metadataSources = new MetadataSources(builder.build());
metadataSources.addAnnotatedClass(Entity1.class);
metadataSources.addAnnotatedClass(Entity2.class);
metadataSources.addAnnotatedClass(Entity3.class);
metadataSources.addAnnotatedClass(Entity4.class);
Metadata metadata = metadataSources.buildMetadata();
for (PersistentClass entityBinding : metadata.getEntityBindings()) {
if (!entityBinding.isInherited())
((RootClass)entityBinding).setCacheConcurrencyStrategy(accessType.getExternalName());
}
return metadata.buildSessionFactory();
}
/**
* Starts Hibernate.
*
* @param accessType Cache access type.
* @param igniteInstanceName Ignite instance name.
* @return Session factory.
*/
private SessionFactory startHibernate(org.hibernate.cache.spi.access.AccessType accessType, String igniteInstanceName) {
StandardServiceRegistryBuilder builder = registryBuilder();
for (Map.Entry<String, String> e : hibernateProperties(igniteInstanceName, accessType.name()).entrySet())
builder.applySetting(e.getKey(), e.getValue());
// Use the same cache for Entity and Entity2.
builder.applySetting(REGION_CACHE_PROPERTY + ENTITY2_NAME, ENTITY_NAME);
StandardServiceRegistry srvcRegistry = builder.build();
MetadataSources metadataSources = new MetadataSources(srvcRegistry);
for (Class entityClass : getAnnotatedClasses())
metadataSources.addAnnotatedClass(entityClass);
Metadata metadata = metadataSources.buildMetadata();
for (PersistentClass entityBinding : metadata.getEntityBindings()) {
if (!entityBinding.isInherited())
((RootClass)entityBinding).setCacheConcurrencyStrategy(accessType.getExternalName());
}
for (org.hibernate.mapping.Collection collectionBinding : metadata.getCollectionBindings())
collectionBinding.setCacheConcurrencyStrategy(accessType.getExternalName() );
return metadata.buildSessionFactory();
}
/**
* @param accessType Cache access typr.
* @param igniteInstanceName Name of the grid providing caches.
* @return Session factory.
*/
private SessionFactory startHibernate(AccessType accessType, String igniteInstanceName) {
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder();
builder.applySetting("hibernate.connection.url", CONNECTION_URL);
for (Map.Entry<String, String> e : HibernateL2CacheSelfTest.hibernateProperties(igniteInstanceName, accessType.name()).entrySet())
builder.applySetting(e.getKey(), e.getValue());
builder.applySetting(USE_STRUCTURED_CACHE, "true");
builder.applySetting(REGION_CACHE_PROPERTY + ENTITY1_NAME, "cache1");
builder.applySetting(REGION_CACHE_PROPERTY + ENTITY2_NAME, "cache2");
builder.applySetting(REGION_CACHE_PROPERTY + DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME, DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME);
builder.applySetting(REGION_CACHE_PROPERTY + DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME, DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME);
MetadataSources metadataSources = new MetadataSources(builder.build());
metadataSources.addAnnotatedClass(Entity1.class);
metadataSources.addAnnotatedClass(Entity2.class);
metadataSources.addAnnotatedClass(Entity3.class);
metadataSources.addAnnotatedClass(Entity4.class);
Metadata metadata = metadataSources.buildMetadata();
for (PersistentClass entityBinding : metadata.getEntityBindings()) {
if (!entityBinding.isInherited())
((RootClass)entityBinding).setCacheConcurrencyStrategy(accessType.getExternalName());
}
return metadata.buildSessionFactory();
}
/**
* Starts Hibernate.
*
* @param accessType Cache access type.
* @param igniteInstanceName Ignite instance name.
* @return Session factory.
*/
private SessionFactory startHibernate(org.hibernate.cache.spi.access.AccessType accessType, String igniteInstanceName) {
StandardServiceRegistryBuilder builder = registryBuilder();
for (Map.Entry<String, String> e : hibernateProperties(igniteInstanceName, accessType.name()).entrySet())
builder.applySetting(e.getKey(), e.getValue());
// Use the same cache for Entity and Entity2.
builder.applySetting(REGION_CACHE_PROPERTY + ENTITY2_NAME, ENTITY_NAME);
StandardServiceRegistry srvcRegistry = builder.build();
MetadataSources metadataSources = new MetadataSources(srvcRegistry);
for (Class entityClass : getAnnotatedClasses())
metadataSources.addAnnotatedClass(entityClass);
Metadata metadata = metadataSources.buildMetadata();
for (PersistentClass entityBinding : metadata.getEntityBindings()) {
if (!entityBinding.isInherited())
((RootClass) entityBinding).setCacheConcurrencyStrategy(accessType.getExternalName());
}
for (org.hibernate.mapping.Collection collectionBinding : metadata.getCollectionBindings())
collectionBinding.setCacheConcurrencyStrategy(accessType.getExternalName());
return metadata.buildSessionFactory();
}
public CreateKeySecondPass(RootClass rootClass) {
this.rootClass = rootClass;
}
private Property bind(Property prop) {
if (isId) {
final RootClass rootClass = ( RootClass ) holder.getPersistentClass();
//if an xToMany, it as to be wrapped today.
//FIXME this pose a problem as the PK is the class instead of the associated class which is not really compliant with the spec
if ( isXToMany || entityBinder.wrapIdsInEmbeddedComponents() ) {
Component identifier = (Component) rootClass.getIdentifier();
if (identifier == null) {
identifier = AnnotationBinder.createComponent(
holder,
new PropertyPreloadedData(null, null, null),
true,
false,
buildingContext
);
rootClass.setIdentifier( identifier );
identifier.setNullValue( "undefined" );
rootClass.setEmbeddedIdentifier( true );
rootClass.setIdentifierMapper( identifier );
}
//FIXME is it good enough?
identifier.addProperty( prop );
}
else {
rootClass.setIdentifier( ( KeyValue ) getValue() );
if (embedded) {
rootClass.setEmbeddedIdentifier( true );
}
else {
rootClass.setIdentifierProperty( prop );
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
declaringClass,
inheritanceStatePerClass,
buildingContext
);
if (superclass != null) {
superclass.setDeclaredIdentifierProperty(prop);
}
else {
//we know the property is on the actual entity
rootClass.setDeclaredIdentifierProperty( prop );
}
}
}
}
else {
holder.addProperty( prop, columns, declaringClass );
}
return prop;
}
public boolean isRootEntity() {
// This is the best option I can think of here since PersistentClass is most likely not yet fully populated
return persistentClass instanceof RootClass;
}
private void bindRootEntity(EntityHierarchySourceImpl hierarchySource, RootClass rootEntityDescriptor) {
final MappingDocument mappingDocument = hierarchySource.getRoot().sourceMappingDocument();
bindBasicEntityValues(
mappingDocument,
hierarchySource.getRoot(),
rootEntityDescriptor
);
final Table primaryTable = bindEntityTableSpecification(
mappingDocument,
hierarchySource.getRoot().getPrimaryTable(),
null,
hierarchySource.getRoot(),
rootEntityDescriptor
);
rootEntityDescriptor.setTable( primaryTable );
if ( log.isDebugEnabled() ) {
log.debugf( "Mapping class: %s -> %s", rootEntityDescriptor.getEntityName(), primaryTable.getName() );
}
rootEntityDescriptor.setOptimisticLockStyle( hierarchySource.getOptimisticLockStyle() );
rootEntityDescriptor.setMutable( hierarchySource.isMutable() );
rootEntityDescriptor.setWhere( hierarchySource.getWhere() );
rootEntityDescriptor.setExplicitPolymorphism( hierarchySource.isExplicitPolymorphism() );
bindEntityIdentifier(
mappingDocument,
hierarchySource,
rootEntityDescriptor
);
if ( hierarchySource.getVersionAttributeSource() != null ) {
bindEntityVersion(
mappingDocument,
hierarchySource,
rootEntityDescriptor
);
}
if ( hierarchySource.getDiscriminatorSource() != null ) {
bindEntityDiscriminator(
mappingDocument,
hierarchySource,
rootEntityDescriptor
);
}
applyCaching( mappingDocument, hierarchySource.getCaching(), rootEntityDescriptor );
// Primary key constraint
rootEntityDescriptor.createPrimaryKey();
bindAllEntityAttributes(
mappingDocument,
hierarchySource.getRoot(),
rootEntityDescriptor
);
if ( hierarchySource.getNaturalIdCaching() != null ) {
if ( hierarchySource.getNaturalIdCaching().getRequested() == TruthValue.TRUE ) {
rootEntityDescriptor.setNaturalIdCacheRegionName( hierarchySource.getNaturalIdCaching().getRegion() );
}
}
}
private void applyCaching(MappingDocument mappingDocument, Caching caching, RootClass rootEntityDescriptor) {
if ( caching == null || caching.getRequested() == TruthValue.UNKNOWN ) {
// see if JPA's SharedCacheMode indicates we should implicitly apply caching
//
// here we only really look for ALL. Ideally we could look at NONE too as a means
// to selectively disable all caching, but historically hbm.xml mappings were processed
// outside this concept and whether to cache or not was defined wholly by what
// is defined in the mapping document. So for backwards compatibility we
// do not consider ENABLE_SELECTIVE nor DISABLE_SELECTIVE here.
//
// Granted, ALL was not historically considered either, but I have a practical
// reason for wanting to support this... our legacy tests built using
// Configuration applied a similar logic but that capability is no longer
// accessible from Configuration
switch ( mappingDocument.getBuildingOptions().getSharedCacheMode() ) {
case ALL: {
caching = new Caching(
null,
mappingDocument.getBuildingOptions().getImplicitCacheAccessType(),
false,
TruthValue.UNKNOWN
);
break;
}
case NONE: {
// Ideally we'd disable all caching...
break;
}
case ENABLE_SELECTIVE: {
// this is default behavior for hbm.xml
break;
}
case DISABLE_SELECTIVE: {
// really makes no sense for hbm.xml
break;
}
default: {
// null or UNSPECIFIED, nothing to do. IMO for hbm.xml this is equivalent
// to ENABLE_SELECTIVE
break;
}
}
}
if ( caching == null || caching.getRequested() == TruthValue.FALSE ) {
return;
}
if ( caching.getAccessType() != null ) {
rootEntityDescriptor.setCacheConcurrencyStrategy( caching.getAccessType().getExternalName() );
}
else {
rootEntityDescriptor.setCacheConcurrencyStrategy( mappingDocument.getBuildingOptions().getImplicitCacheAccessType().getExternalName() );
}
rootEntityDescriptor.setCacheRegionName( caching.getRegion() );
rootEntityDescriptor.setLazyPropertiesCacheable( caching.isCacheLazyProperties() );
rootEntityDescriptor.setCached( caching.getRequested() != TruthValue.UNKNOWN );
}
private void bindEntityIdentifier(
MappingDocument mappingDocument,
EntityHierarchySourceImpl hierarchySource,
RootClass rootEntityDescriptor) {
switch ( hierarchySource.getIdentifierSource().getNature() ) {
case SIMPLE: {
bindSimpleEntityIdentifier(
mappingDocument,
hierarchySource,
rootEntityDescriptor
);
break;
}
case AGGREGATED_COMPOSITE: {
bindAggregatedCompositeEntityIdentifier(
mappingDocument,
hierarchySource,
rootEntityDescriptor
);
break;
}
case NON_AGGREGATED_COMPOSITE: {
bindNonAggregatedCompositeEntityIdentifier(
mappingDocument,
hierarchySource,
rootEntityDescriptor
);
break;
}
default: {
throw new MappingException(
String.format(
Locale.ENGLISH,
"Unexpected entity identifier nature [%s] for entity %s",
hierarchySource.getIdentifierSource().getNature(),
hierarchySource.getRoot().getEntityNamingSource().getEntityName()
),
mappingDocument.getOrigin()
);
}
}
}
private void bindSimpleEntityIdentifier(
MappingDocument sourceDocument,
final EntityHierarchySourceImpl hierarchySource,
RootClass rootEntityDescriptor) {
final IdentifierSourceSimple idSource = (IdentifierSourceSimple) hierarchySource.getIdentifierSource();
final SimpleValue idValue = new SimpleValue(
sourceDocument,
rootEntityDescriptor.getTable()
);
rootEntityDescriptor.setIdentifier( idValue );
bindSimpleValueType(
sourceDocument,
idSource.getIdentifierAttributeSource().getTypeInformation(),
idValue
);
final String propertyName = idSource.getIdentifierAttributeSource().getName();
if ( propertyName == null || !rootEntityDescriptor.hasPojoRepresentation() ) {
if ( !idValue.isTypeSpecified() ) {
throw new MappingException(
"must specify an identifier type: " + rootEntityDescriptor.getEntityName(),
sourceDocument.getOrigin()
);
}
}
else {
idValue.setTypeUsingReflection( rootEntityDescriptor.getClassName(), propertyName );
}
relationalObjectBinder.bindColumnsAndFormulas(
sourceDocument,
( (RelationalValueSourceContainer) idSource.getIdentifierAttributeSource() ).getRelationalValueSources(),
idValue,
false,
new RelationalObjectBinder.ColumnNamingDelegate() {
@Override
public Identifier determineImplicitName(final LocalMetadataBuildingContext context) {
context.getBuildingOptions().getImplicitNamingStrategy().determineIdentifierColumnName(
new ImplicitIdentifierColumnNameSource() {
@Override
public EntityNaming getEntityNaming() {
return hierarchySource.getRoot().getEntityNamingSource();
}
@Override
public AttributePath getIdentifierAttributePath() {
return idSource.getIdentifierAttributeSource().getAttributePath();
}
@Override
public MetadataBuildingContext getBuildingContext() {
return context;
}
}
);
return database.toIdentifier( propertyName );
}
}
);
if ( propertyName != null ) {
Property prop = new Property();
prop.setValue( idValue );
bindProperty(
sourceDocument,
idSource.getIdentifierAttributeSource(),
prop
);
rootEntityDescriptor.setIdentifierProperty( prop );
rootEntityDescriptor.setDeclaredIdentifierProperty( prop );
}
makeIdentifier(
sourceDocument,
idSource.getIdentifierGeneratorDescriptor(),
idSource.getUnsavedValue(),
idValue
);
}