use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.
the class CriteriaQueryTranslator method getPathInfo.
private CriteriaInfoProvider getPathInfo(String path) {
StringTokenizer tokens = new StringTokenizer(path, ".");
String componentPath = "";
// start with the 'rootProvider'
CriteriaInfoProvider provider = nameCriteriaInfoMap.get(rootEntityName);
while (tokens.hasMoreTokens()) {
componentPath += tokens.nextToken();
final Type type = provider.getType(componentPath);
if (type.isAssociationType()) {
// CollectionTypes are always also AssociationTypes - but there's not always an associated entity...
final AssociationType atype = (AssociationType) type;
final CollectionType ctype = type.isCollectionType() ? (CollectionType) type : null;
final Type elementType = (ctype != null) ? ctype.getElementType(sessionFactory) : null;
// is the association a collection of components or value-types? (i.e a colloction of valued types?)
if (ctype != null && elementType.isComponentType()) {
provider = new ComponentCollectionCriteriaInfoProvider(helper.getCollectionPersister(ctype.getRole()));
} else if (ctype != null && !elementType.isEntityType()) {
provider = new ScalarCollectionCriteriaInfoProvider(helper, ctype.getRole());
} else {
provider = new EntityCriteriaInfoProvider((Queryable) sessionFactory.getEntityPersister(atype.getAssociatedEntityName(sessionFactory)));
}
componentPath = "";
} else if (type.isComponentType()) {
if (!tokens.hasMoreTokens()) {
throw new QueryException("Criteria objects cannot be created directly on components. Create a criteria on " + "owning entity and use a dotted property to access component property: " + path);
} else {
componentPath += '.';
}
} else {
throw new QueryException("not an association: " + componentPath);
}
}
return provider;
}
use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.
the class CustomLoader method determineAppropriateOwnerPersister.
private Queryable determineAppropriateOwnerPersister(NonScalarReturn ownerDescriptor) {
String entityName = null;
if (ownerDescriptor instanceof RootReturn) {
entityName = ((RootReturn) ownerDescriptor).getEntityName();
} else if (ownerDescriptor instanceof CollectionReturn) {
CollectionReturn collRtn = (CollectionReturn) ownerDescriptor;
String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
CollectionPersister persister = getFactory().getMetamodel().collectionPersister(role);
EntityType ownerType = (EntityType) persister.getElementType();
entityName = ownerType.getAssociatedEntityName(getFactory());
} else if (ownerDescriptor instanceof FetchReturn) {
FetchReturn fetchRtn = (FetchReturn) ownerDescriptor;
Queryable persister = determineAppropriateOwnerPersister(fetchRtn.getOwner());
Type ownerType = persister.getPropertyType(fetchRtn.getOwnerProperty());
if (ownerType.isEntityType()) {
entityName = ((EntityType) ownerType).getAssociatedEntityName(getFactory());
} else if (ownerType.isCollectionType()) {
Type ownerCollectionElementType = ((CollectionType) ownerType).getElementType(getFactory());
if (ownerCollectionElementType.isEntityType()) {
entityName = ((EntityType) ownerCollectionElementType).getAssociatedEntityName(getFactory());
}
}
}
if (entityName == null) {
throw new HibernateException("Could not determine fetch owner : " + ownerDescriptor);
}
return (Queryable) getFactory().getMetamodel().entityPersister(entityName);
}
use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.
the class StatefulPersistenceContext method getCollectionOwner.
@Override
public Object getCollectionOwner(Serializable key, CollectionPersister collectionPersister) throws MappingException {
// todo : we really just need to add a split in the notions of:
// 1) collection key
// 2) collection owner key
// these 2 are not always the same. Same is true in the case of ToOne associations with property-ref...
final EntityPersister ownerPersister = collectionPersister.getOwnerEntityPersister();
if (ownerPersister.getIdentifierType().getReturnedClass().isInstance(key)) {
return getEntity(session.generateEntityKey(key, collectionPersister.getOwnerEntityPersister()));
}
// 1) The incoming key could be the entity itself...
if (ownerPersister.isInstance(key)) {
final Serializable owenerId = ownerPersister.getIdentifier(key, session);
if (owenerId == null) {
return null;
}
return getEntity(session.generateEntityKey(owenerId, ownerPersister));
}
final CollectionType collectionType = collectionPersister.getCollectionType();
// a) try by EntityUniqueKey
if (collectionType.getLHSPropertyName() != null) {
final Object owner = getEntity(new EntityUniqueKey(ownerPersister.getEntityName(), collectionType.getLHSPropertyName(), key, collectionPersister.getKeyType(), ownerPersister.getEntityMode(), session.getFactory()));
if (owner != null) {
return owner;
}
// b) try by EntityKey, which means we need to resolve owner-key -> collection-key
// IMPL NOTE : yes if we get here this impl is very non-performant, but PersistenceContext
// was never designed to handle this case; adding that capability for real means splitting
// the notions of:
// 1) collection key
// 2) collection owner key
// these 2 are not always the same (same is true in the case of ToOne associations with
// property-ref). That would require changes to (at least) CollectionEntry and quite
// probably changes to how the sql for collection initializers are generated
//
// We could also possibly see if the referenced property is a natural id since we already have caching
// in place of natural id snapshots. BUt really its better to just do it the right way ^^ if we start
// going that route
final Serializable ownerId = ownerPersister.getIdByUniqueKey(key, collectionType.getLHSPropertyName(), session);
return getEntity(session.generateEntityKey(ownerId, ownerPersister));
}
// as a last resort this is what the old code did...
return getEntity(session.generateEntityKey(key, collectionPersister.getOwnerEntityPersister()));
}
use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.
the class EntityGraphQueryHint method getFromElements.
private List<FromElement> getFromElements(List attributeNodes, FromElement origin, FromClause fromClause, HqlSqlWalker walker, Map<String, FromElement> explicitFetches) {
final List<FromElement> fromElements = new ArrayList<FromElement>();
for (Object obj : attributeNodes) {
final AttributeNode<?> attributeNode = (AttributeNode<?>) obj;
final String attributeName = attributeNode.getAttributeName();
final String className = origin.getClassName();
// TODO: This is ignored by collection types and probably wrong for entity types. Presumably it screws
// with inheritance.
final String role = className + "." + attributeName;
final String classAlias = origin.getClassAlias();
final String originTableAlias = origin.getTableAlias();
final Type propertyType = origin.getPropertyType(attributeName, attributeName);
try {
FromElement fromElement = explicitFetches.get(role);
boolean explicitFromElement = false;
if (fromElement == null) {
if (propertyType.isEntityType()) {
final EntityType entityType = (EntityType) propertyType;
final String[] columns = origin.toColumns(originTableAlias, attributeName, false);
final String tableAlias = walker.getAliasGenerator().createName(entityType.getAssociatedEntityName());
final FromElementFactory fromElementFactory = new FromElementFactory(fromClause, origin, attributeName, classAlias, columns, false);
final JoinSequence joinSequence = walker.getSessionFactoryHelper().createJoinSequence(false, entityType, tableAlias, JoinType.LEFT_OUTER_JOIN, columns);
fromElement = fromElementFactory.createEntityJoin(entityType.getAssociatedEntityName(), tableAlias, joinSequence, true, walker.isInFrom(), entityType, role, null);
} else if (propertyType.isCollectionType()) {
CollectionType collectionType = (CollectionType) propertyType;
final String[] columns = origin.toColumns(originTableAlias, attributeName, false);
final FromElementFactory fromElementFactory = new FromElementFactory(fromClause, origin, attributeName, classAlias, columns, false);
final QueryableCollection queryableCollection = walker.getSessionFactoryHelper().requireQueryableCollection(collectionType.getRole());
fromElement = fromElementFactory.createCollection(queryableCollection, collectionType.getRole(), JoinType.LEFT_OUTER_JOIN, true, false);
}
} else {
explicitFromElement = true;
fromElement.setInProjectionList(true);
fromElement.setFetch(true);
}
if (fromElement != null) {
if (!explicitFromElement) {
fromElements.add(fromElement);
}
// recurse into subgraphs
for (Subgraph<?> subgraph : attributeNode.getSubgraphs().values()) {
fromElements.addAll(getFromElements(subgraph.getAttributeNodes(), fromElement, fromClause, walker, explicitFetches));
}
}
} catch (Exception e) {
throw new QueryException("Could not apply the EntityGraph to the Query!", e);
}
}
return fromElements;
}
use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.
the class DefaultRefreshEventListener method evictCachedCollections.
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 CollectionRegionAccessStrategy cache = collectionPersister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(id, collectionPersister, source.getFactory(), source.getTenantIdentifier());
final SoftLock lock = cache.lockItem(source, ck, null);
source.getActionQueue().registerProcess(new AfterTransactionCompletionProcess() {
@Override
public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) {
cache.unlockItem(session, ck, lock);
}
});
cache.remove(source, ck);
}
} else if (type.isComponentType()) {
CompositeType actype = (CompositeType) type;
evictCachedCollections(actype.getSubtypes(), id, source);
}
}
}
Aggregations