下面列出了org.hibernate.type.Type#isComponentType ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void prepareEntityIdentifierDefinition() {
if ( entityIdentifierDefinition != null ) {
return;
}
final Type idType = getIdentifierType();
if ( !idType.isComponentType() ) {
entityIdentifierDefinition =
EntityIdentifierDefinitionHelper.buildSimpleEncapsulatedIdentifierDefinition( this );
return;
}
final CompositeType cidType = (CompositeType) idType;
if ( !cidType.isEmbedded() ) {
entityIdentifierDefinition =
EntityIdentifierDefinitionHelper.buildEncapsulatedCompositeIdentifierDefinition( this );
return;
}
entityIdentifierDefinition =
EntityIdentifierDefinitionHelper.buildNonEncapsulatedCompositeIdentifierDefinition( this );
}
private String getPathEntityName(String path) {
Queryable persister = ( Queryable ) sessionFactory.getEntityPersister( rootEntityName );
StringTokenizer tokens = new StringTokenizer( path, "." );
String componentPath = "";
while ( tokens.hasMoreTokens() ) {
componentPath += tokens.nextToken();
Type type = persister.toType( componentPath );
if ( type.isAssociationType() ) {
AssociationType atype = ( AssociationType ) type;
persister = ( Queryable ) sessionFactory.getEntityPersister(
atype.getAssociatedEntityName( sessionFactory )
);
componentPath = "";
}
else if ( type.isComponentType() ) {
componentPath += '.';
}
else {
throw new QueryException( "not an association: " + componentPath );
}
}
return persister.getEntityName();
}
/**
* Cascade an action to the child or children
*/
private void cascadeProperty(
final Object child,
final Type type,
final CascadeStyle style,
final Object anything,
final boolean isCascadeDeleteEnabled) throws HibernateException {
if (child!=null) {
if ( type.isAssociationType() ) {
AssociationType associationType = (AssociationType) type;
if ( cascadeAssociationNow( associationType ) ) {
cascadeAssociation(
child,
type,
style,
anything,
isCascadeDeleteEnabled
);
}
}
else if ( type.isComponentType() ) {
cascadeComponent( child, (AbstractComponentType) type, anything );
}
}
}
private void initCollectionPropertyMap(String aliasName, Type type, String[] columnAliases, String[] columnNames) {
collectionPropertyColumnAliases.put( aliasName, columnAliases );
collectionPropertyColumnNames.put( aliasName, columnNames );
if ( type.isComponentType() ) {
CompositeType ct = (CompositeType) type;
String[] propertyNames = ct.getPropertyNames();
for ( int i = 0; i < propertyNames.length; i++ ) {
String name = propertyNames[i];
collectionPropertyColumnAliases.put( aliasName + "." + name, columnAliases[i] );
collectionPropertyColumnNames.put( aliasName + "." + name, columnNames[i] );
}
}
}
/**
* Visit a property value. Dispatch to the
* correct handler for the property type.
* @param value
* @param type
* @throws HibernateException
*/
final Object processValue(Object value, Type type) throws HibernateException {
if ( type.isCollectionType() ) {
//even process null collections
return processCollection( value, (CollectionType) type );
}
else if ( type.isEntityType() ) {
return processEntity( value, (EntityType) type );
}
else if ( type.isComponentType() ) {
return processComponent( value, (CompositeType) type );
}
else {
return null;
}
}
private void evictCachedCollections(Type[] types, Serializable id, EventSource source)
throws HibernateException {
for ( Type type : types ) {
if ( type.isCollectionType() ) {
CollectionPersister collectionPersister = source.getFactory().getMetamodel().collectionPersister( ( (CollectionType) type ).getRole() );
if ( collectionPersister.hasCache() ) {
final CollectionDataAccess cache = collectionPersister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(
id,
collectionPersister,
source.getFactory(),
source.getTenantIdentifier()
);
final SoftLock lock = cache.lockItem( source, ck, null );
cache.remove( source, ck );
source.getActionQueue().registerProcess( (success, session) -> cache.unlockItem( session, ck, lock ) );
}
}
else if ( type.isComponentType() ) {
CompositeType actype = (CompositeType) type;
evictCachedCollections( actype.getSubtypes(), id, source );
}
}
}
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
ArrayList list = new ArrayList();
Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
if ( type.isComponentType() ) {
AbstractComponentType actype = (AbstractComponentType) type;
Type[] types = actype.getSubtypes();
for ( int i=0; i<types.length; i++ ) {
for ( int j=0; j<values.length; j++ ) {
Object subval = values[j]==null ?
null :
actype.getPropertyValues( values[j], EntityMode.POJO )[i];
list.add( new TypedValue( types[i], subval, EntityMode.POJO ) );
}
}
}
else {
for ( int j=0; j<values.length; j++ ) {
list.add( new TypedValue( type, values[j], EntityMode.POJO ) );
}
}
return (TypedValue[]) list.toArray( new TypedValue[ list.size() ] );
}
@Override
public void finishingCollectionElements(CollectionElementDefinition elementDefinition) {
final Type elementType = elementDefinition.getType();
if ( elementType.isAnyType() ) {
// nothing to do because the element graph was not pushed in #startingCollectionElement..
}
else if ( elementType.isComponentType() || elementType.isAssociationType()) {
// pop it from the stack
final ExpandingFetchSource popped = popFromStack();
// validation
if ( ! CollectionFetchableElement.class.isInstance( popped ) ) {
throw new WalkingException( "Mismatched FetchSource from stack on pop" );
}
}
log.tracef(
"%s Finished collection element graph : %s",
StringHelper.repeat( "<<", fetchSourceStack.size() ),
elementDefinition.getCollectionDefinition().getCollectionPersister().getRole()
);
}
/**
* For an entity class, add to a list of associations to be fetched
* by outerjoin
*/
private final void walkEntityTree(
final OuterJoinLoadable persister,
final String alias,
final String path,
final int currentDepth)
throws MappingException {
int n = persister.countSubclassProperties();
for ( int i=0; i<n; i++ ) {
Type type = persister.getSubclassPropertyType(i);
if ( type.isAssociationType() ) {
walkEntityAssociationTree(
(AssociationType) type,
persister,
i,
alias,
path,
persister.isSubclassPropertyNullable(i),
currentDepth
);
}
else if ( type.isComponentType() ) {
walkComponentTree(
(AbstractComponentType) type,
i,
0,
persister,
alias,
subPath( path, persister.getSubclassPropertyName(i) ),
currentDepth
);
}
}
}
private int resolveAsNakedPropertyRef() {
FromElement fromElement = locateSingleFromElement();
if (fromElement == null) {
return UNKNOWN;
}
Queryable persister = fromElement.getQueryable();
if (persister == null) {
return UNKNOWN;
}
Type propertyType = getNakedPropertyType(fromElement);
if (propertyType == null) {
// assume this ident's text does *not* refer to a property on the given persister
return UNKNOWN;
}
if ((propertyType.isComponentType() || propertyType.isAssociationType() )) {
return COMPONENT_REF;
}
setFromElement(fromElement);
String property = getText();
String[] columns = getWalker().isSelectStatement()
? persister.toColumns(fromElement.getTableAlias(), property)
: persister.toColumns(property);
String text = StringHelper.join(", ", columns);
setText(columns.length == 1 ? text : "(" + text + ")");
setType(SqlTokenTypes.SQL_TOKEN);
// these pieces are needed for usage in select clause
super.setDataType(propertyType);
nakedPropertyRef = true;
return PROPERTY_REF;
}
/**
* Return null if the argument is an "unsaved" entity (ie. one with no existing database row), or the
* input argument otherwise. This is how Hibernate avoids foreign key constraint violations.
*
* @param value An entity attribute value
* @param type An entity attribute type
*
* @return {@code null} if the argument is an unsaved entity; otherwise return the argument.
*/
private Object nullifyTransientReferences(final Object value, final Type type) {
if ( value == null ) {
return null;
}
else if ( type.isEntityType() ) {
final EntityType entityType = (EntityType) type;
if ( entityType.isOneToOne() ) {
return value;
}
else {
final String entityName = entityType.getAssociatedEntityName();
return isNullifiable( entityName, value ) ? null : value;
}
}
else if ( type.isAnyType() ) {
return isNullifiable( null, value ) ? null : value;
}
else if ( type.isComponentType() ) {
final CompositeType actype = (CompositeType) type;
final Object[] subvalues = actype.getPropertyValues( value, session );
final Type[] subtypes = actype.getSubtypes();
boolean substitute = false;
for ( int i = 0; i < subvalues.length; i++ ) {
final Object replacement = nullifyTransientReferences( subvalues[i], subtypes[i] );
if ( replacement != subvalues[i] ) {
substitute = true;
subvalues[i] = replacement;
}
}
if ( substitute ) {
// todo : need to account for entity mode on the CompositeType interface :(
actype.setPropertyValues( value, subvalues, EntityMode.POJO );
}
return value;
}
else {
return value;
}
}
protected void appendComponentCondition(
String path,
Object component,
CompositeType type,
Criteria criteria,
CriteriaQuery criteriaQuery,
StringBuilder buf) {
if ( component != null ) {
final String[] propertyNames = type.getPropertyNames();
final Object[] values = type.getPropertyValues( component, getEntityMode( criteria, criteriaQuery ) );
final Type[] subtypes = type.getSubtypes();
for ( int i=0; i<propertyNames.length; i++ ) {
final String subPath = StringHelper.qualify( path, propertyNames[i] );
final Object value = values[i];
if ( isPropertyIncluded( value, subPath, subtypes[i] ) ) {
final Type subtype = subtypes[i];
if ( subtype.isComponentType() ) {
appendComponentCondition(
subPath,
value,
(CompositeType) subtype,
criteria,
criteriaQuery,
buf
);
}
else {
appendPropertyCondition(
subPath,
value,
criteria,
criteriaQuery,
buf
);
}
}
}
}
}
private boolean hasAssociation(CompositeType componentType) {
for ( Type subType : componentType.getSubtypes() ) {
if ( subType.isEntityType() ) {
return true;
}
else if ( subType.isComponentType() && hasAssociation( ( (CompositeType) subType ) ) ) {
return true;
}
}
return false;
}
private boolean indicatesCollection(Type type) {
if ( type.isCollectionType() ) {
return true;
}
else if ( type.isComponentType() ) {
Type[] subtypes = ( (CompositeType) type ).getSubtypes();
for ( int i = 0; i < subtypes.length; i++ ) {
if ( indicatesCollection( subtypes[i] ) ) {
return true;
}
}
}
return false;
}
/**
* Cascade an action to the child or children
*/
private static void cascadeProperty(
final CascadingAction action,
final CascadePoint cascadePoint,
final EventSource eventSource,
final int componentPathStackDepth,
final Object parent,
final Object child,
final Type type,
final CascadeStyle style,
final String propertyName,
final Object anything,
final boolean isCascadeDeleteEnabled) throws HibernateException {
if ( child != null ) {
if ( type.isAssociationType() ) {
final AssociationType associationType = (AssociationType) type;
if ( cascadeAssociationNow( cascadePoint, associationType ) ) {
cascadeAssociation(
action,
cascadePoint,
eventSource,
componentPathStackDepth,
parent,
child,
type,
style,
anything,
isCascadeDeleteEnabled
);
}
}
else if ( type.isComponentType() ) {
cascadeComponent(
action,
cascadePoint,
eventSource,
componentPathStackDepth,
parent,
child,
(CompositeType) type,
anything
);
}
}
cascadeLogicalOneToOneOrphanRemoval(
action,
eventSource,
componentPathStackDepth,
parent,
child,
type,
style,
propertyName,
isCascadeDeleteEnabled );
}
protected void appendComponentCondition(
String path,
Object component,
AbstractComponentType type,
Criteria criteria,
CriteriaQuery criteriaQuery,
StringBuffer buf)
throws HibernateException {
if (component!=null) {
String[] propertyNames = type.getPropertyNames();
Object[] values = type.getPropertyValues( component, getEntityMode(criteria, criteriaQuery) );
Type[] subtypes = type.getSubtypes();
for (int i=0; i<propertyNames.length; i++) {
String subpath = StringHelper.qualify( path, propertyNames[i] );
Object value = values[i];
if ( isPropertyIncluded( value, subpath, subtypes[i] ) ) {
Type subtype = subtypes[i];
if ( subtype.isComponentType() ) {
appendComponentCondition(
subpath,
value,
(AbstractComponentType) subtype,
criteria,
criteriaQuery,
buf
);
}
else {
appendPropertyCondition(
subpath,
value,
criteria,
criteriaQuery,
buf
);
}
}
}
}
}
/**
* For a collection role, return a list of associations to be fetched by outerjoin
*/
private void walkCollectionTree(
final QueryableCollection persister,
final String alias,
final PropertyPath path,
final int currentDepth) throws MappingException {
if ( persister.isOneToMany() ) {
walkEntityTree(
(OuterJoinLoadable) persister.getElementPersister(),
alias,
path,
currentDepth
);
}
else {
Type type = persister.getElementType();
if ( type.isAssociationType() ) {
// a many-to-many;
// decrement currentDepth here to allow join across the association table
// without exceeding MAX_FETCH_DEPTH (i.e. the "currentDepth - 1" bit)
AssociationType associationType = (AssociationType) type;
String[] aliasedLhsColumns = persister.getElementColumnNames( alias );
String[] lhsColumns = persister.getElementColumnNames();
// if the current depth is 0, the root thing being loaded is the
// many-to-many collection itself. Here, it is alright to use
// an inner join...
boolean useInnerJoin = currentDepth == 0;
final JoinType joinType = getJoinType(
associationType,
persister.getFetchMode(),
path,
persister.getTableName(),
lhsColumns,
!useInnerJoin,
currentDepth - 1,
null //operations which cascade as far as the collection also cascade to collection elements
);
addAssociationToJoinTreeIfNecessary(
associationType,
aliasedLhsColumns,
alias,
path,
currentDepth - 1,
joinType
);
}
else if ( type.isComponentType() ) {
walkCompositeElementTree(
(CompositeType) type,
persister.getElementColumnNames(),
persister,
alias,
path,
currentDepth
);
}
}
}
private CollectionFetchableIndex buildIndexGraph() {
final CollectionPersister persister = collectionQuerySpace.getCollectionPersister();
if ( persister.hasIndex() ) {
final Type type = persister.getIndexType();
if ( type.isAssociationType() ) {
if ( type.isEntityType() ) {
final EntityPersister indexPersister = persister.getFactory().getEntityPersister(
( (EntityType) type ).getAssociatedEntityName()
);
final ExpandingEntityQuerySpace entityQuerySpace = QuerySpaceHelper.INSTANCE.makeEntityQuerySpace(
collectionQuerySpace,
indexPersister,
CollectionPropertyNames.COLLECTION_INDICES,
(EntityType) persister.getIndexType(),
collectionQuerySpace.getExpandingQuerySpaces().generateImplicitUid(),
collectionQuerySpace.canJoinsBeRequired(),
allowIndexJoin
);
return new CollectionFetchableIndexEntityGraph( this, entityQuerySpace );
}
else if ( type.isAnyType() ) {
return new CollectionFetchableIndexAnyGraph( this );
}
}
else if ( type.isComponentType() ) {
final ExpandingCompositeQuerySpace compositeQuerySpace = QuerySpaceHelper.INSTANCE.makeCompositeQuerySpace(
collectionQuerySpace,
new CompositePropertyMapping(
(CompositeType) persister.getIndexType(),
(PropertyMapping) persister,
""
),
CollectionPropertyNames.COLLECTION_INDICES,
(CompositeType) persister.getIndexType(),
collectionQuerySpace.getExpandingQuerySpaces().generateImplicitUid(),
collectionQuerySpace.canJoinsBeRequired(),
allowIndexJoin
);
return new CollectionFetchableIndexCompositeGraph( this, compositeQuerySpace );
}
}
return null;
}
private CollectionFetchableElement buildElementGraph() {
final CollectionPersister persister = collectionQuerySpace.getCollectionPersister();
final Type type = persister.getElementType();
if ( type.isAssociationType() ) {
if ( type.isEntityType() ) {
final EntityPersister elementPersister = persister.getFactory().getEntityPersister(
( (EntityType) type ).getAssociatedEntityName()
);
final ExpandingEntityQuerySpace entityQuerySpace = QuerySpaceHelper.INSTANCE.makeEntityQuerySpace(
collectionQuerySpace,
elementPersister,
CollectionPropertyNames.COLLECTION_ELEMENTS,
(EntityType) persister.getElementType(),
collectionQuerySpace.getExpandingQuerySpaces().generateImplicitUid(),
collectionQuerySpace.canJoinsBeRequired(),
allowElementJoin
);
return new CollectionFetchableElementEntityGraph( this, entityQuerySpace );
}
else if ( type.isAnyType() ) {
return new CollectionFetchableElementAnyGraph( this );
}
}
else if ( type.isComponentType() ) {
final ExpandingCompositeQuerySpace compositeQuerySpace = QuerySpaceHelper.INSTANCE.makeCompositeQuerySpace(
collectionQuerySpace,
new CompositePropertyMapping(
(CompositeType) persister.getElementType(),
(PropertyMapping) persister,
""
),
CollectionPropertyNames.COLLECTION_ELEMENTS,
(CompositeType) persister.getElementType(),
collectionQuerySpace.getExpandingQuerySpaces().generateImplicitUid(),
collectionQuerySpace.canJoinsBeRequired(),
allowElementJoin
);
return new CollectionFetchableElementCompositeGraph( this, compositeQuerySpace );
}
return null;
}
private void visitAttributeDefinition(AttributeDefinition attributeDefinition, AbstractEntityPersister sourcePersister) {
final PropertyPath subPath = currentPropertyPath.append( attributeDefinition.getName() );
log.debug( "Visiting attribute path : " + subPath.getFullPath() );
if ( attributeDefinition.getType().isAssociationType() ) {
final AssociationAttributeDefinition associationAttributeDefinition =
(AssociationAttributeDefinition) attributeDefinition;
final AssociationKey associationKey = associationAttributeDefinition.getAssociationKey();
if ( isDuplicateAssociationKey( associationKey ) ) {
log.debug( "Property path deemed to be circular : " + subPath.getFullPath() );
strategy.foundCircularAssociation( associationAttributeDefinition );
// EARLY EXIT!!!
return;
}
if ( sourcePersister != null ) {
String[] columns = sourcePersister.toColumns(attributeDefinition.getName());
// Empty columns means that the attribute is not resolvable on this persister
if ( columns.length == 0 ) {
return;
}
}
}
boolean continueWalk = strategy.startingAttribute( attributeDefinition );
if ( continueWalk ) {
final PropertyPath old = currentPropertyPath;
currentPropertyPath = subPath;
try {
final Type attributeType = attributeDefinition.getType();
if ( attributeType.isAssociationType() ) {
visitAssociation( (AssociationAttributeDefinition) attributeDefinition );
}
else if ( attributeType.isComponentType() ) {
visitCompositeDefinition( (CompositionDefinition) attributeDefinition );
}
}
finally {
currentPropertyPath = old;
}
}
strategy.finishingAttribute( attributeDefinition );
}