use of org.hibernate.persister.entity.EntityPersister in project hibernate-orm by hibernate.
the class DotNode method dereferenceCollection.
private void dereferenceCollection(CollectionType collectionType, boolean implicitJoin, boolean indexed, String classAlias, AST parent) throws SemanticException {
dereferenceType = DereferenceType.COLLECTION;
String role = collectionType.getRole();
//foo.bars.size (also handles deprecated stuff like foo.bars.maxelement for backwardness)
boolean isSizeProperty = getNextSibling() != null && CollectionProperties.isAnyCollectionProperty(getNextSibling().getText());
if (isSizeProperty) {
//yuck!
indexed = true;
}
QueryableCollection queryableCollection = getSessionFactoryHelper().requireQueryableCollection(role);
String propName = getPath();
FromClause currentFromClause = getWalker().getCurrentFromClause();
// If the lhs of the join is a "component join", we need to go back to the
// first non-component-join as the origin to properly link aliases and
// join columns
FromElement lhsFromElement = getLhs().getFromElement();
while (lhsFromElement != null && ComponentJoin.class.isInstance(lhsFromElement)) {
lhsFromElement = lhsFromElement.getOrigin();
}
if (lhsFromElement == null) {
throw new QueryException("Unable to locate appropriate lhs");
}
// in all other cases, we should use the table alias
if (getWalker().getStatementType() != SqlTokenTypes.SELECT) {
if (isFromElementUpdateOrDeleteRoot(lhsFromElement)) {
// at this point we know we have the 2 conditions above,
// lets see if we have the mentioned "multi-table" caveat...
boolean useAlias = false;
if (getWalker().getStatementType() != SqlTokenTypes.INSERT) {
final Queryable persister = lhsFromElement.getQueryable();
if (persister.isMultiTable()) {
useAlias = true;
}
}
if (!useAlias) {
final String lhsTableName = lhsFromElement.getQueryable().getTableName();
columns = getFromElement().toColumns(lhsTableName, propertyPath, false, true);
}
}
}
// We do not look for an existing join on the same path, because
// it makes sense to join twice on the same collection role
FromElementFactory factory = new FromElementFactory(currentFromClause, lhsFromElement, propName, classAlias, getColumns(), implicitJoin);
FromElement elem = factory.createCollection(queryableCollection, role, joinType, fetch, indexed);
LOG.debugf("dereferenceCollection() : Created new FROM element for %s : %s", propName, elem);
setImpliedJoin(elem);
// This 'dot' expression now refers to the resulting from element.
setFromElement(elem);
if (isSizeProperty) {
elem.setText("");
elem.setUseWhereFragment(false);
}
if (!implicitJoin) {
EntityPersister entityPersister = elem.getEntityPersister();
if (entityPersister != null) {
getWalker().addQuerySpaces(entityPersister.getQuerySpaces());
}
}
// Always add the collection's query spaces.
getWalker().addQuerySpaces(queryableCollection.getCollectionSpaces());
}
use of org.hibernate.persister.entity.EntityPersister in project hibernate-orm by hibernate.
the class HqlSqlWalker method createFromJoinElement.
@Override
protected void createFromJoinElement(AST path, AST alias, int joinType, AST fetchNode, AST propertyFetch, AST with) throws SemanticException {
boolean fetch = fetchNode != null;
if (fetch && isSubQuery()) {
throw new QueryException("fetch not allowed in subquery from-elements");
}
// the incoming "path" can be either:
// 1) an implicit join path (join p.address.city)
// 2) an entity-join (join com.acme.User)
//
// so make the proper interpretation here...
final EntityPersister entityJoinReferencedPersister = resolveEntityJoinReferencedPersister(path);
if (entityJoinReferencedPersister != null) {
// `path` referenced an entity
final EntityJoinFromElement join = createEntityJoin(entityJoinReferencedPersister, alias, joinType, propertyFetch, with);
((FromReferenceNode) path).setFromElement(join);
} else {
if (path.getType() != SqlTokenTypes.DOT) {
throw new SemanticException("Path expected for join!");
}
DotNode dot = (DotNode) path;
JoinType hibernateJoinType = JoinProcessor.toHibernateJoinType(joinType);
// Tell the dot node about the join type.
dot.setJoinType(hibernateJoinType);
dot.setFetch(fetch);
// Generate an explicit join for the root dot node. The implied joins will be collected and passed up
// to the root dot node.
dot.resolve(true, false, alias == null ? null : alias.getText());
final FromElement fromElement;
if (dot.getDataType() != null && dot.getDataType().isComponentType()) {
if (dot.getDataType().isAnyType()) {
throw new SemanticException("An AnyType attribute cannot be join fetched");
// ^^ because the discriminator (aka, the "meta columns") must be known to the SQL in
// a non-parameterized way.
}
FromElementFactory factory = new FromElementFactory(getCurrentFromClause(), dot.getLhs().getFromElement(), dot.getPropertyPath(), alias == null ? null : alias.getText(), null, false);
fromElement = factory.createComponentJoin((CompositeType) dot.getDataType());
} else {
fromElement = dot.getImpliedJoin();
fromElement.setAllPropertyFetch(propertyFetch != null);
if (with != null) {
if (fetch) {
throw new SemanticException("with-clause not allowed on fetched associations; use filters");
}
handleWithFragment(fromElement, with);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("createFromJoinElement() : " + getASTPrinter().showAsString(fromElement, "-- join tree --"));
}
}
}
use of org.hibernate.persister.entity.EntityPersister in project hibernate-orm by hibernate.
the class FromElementFactory method createElementJoin.
FromElement createElementJoin(QueryableCollection queryableCollection) throws SemanticException {
FromElement elem;
//TODO: always true for now, but not if we later decide to support elements() in the from clause
implied = true;
inElementsFunction = true;
Type elementType = queryableCollection.getElementType();
if (!elementType.isEntityType()) {
throw new IllegalArgumentException("Cannot create element join for a collection of non-entities!");
}
this.queryableCollection = queryableCollection;
SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
FromElement destination = null;
String tableAlias = null;
EntityPersister entityPersister = queryableCollection.getElementPersister();
tableAlias = fromClause.getAliasGenerator().createName(entityPersister.getEntityName());
String associatedEntityName = entityPersister.getEntityName();
EntityPersister targetEntityPersister = sfh.requireClassPersister(associatedEntityName);
// Create the FROM element for the target (the elements of the collection).
destination = createAndAddFromElement(associatedEntityName, classAlias, targetEntityPersister, (EntityType) queryableCollection.getElementType(), tableAlias);
// If the join is implied, then don't include sub-classes on the element.
if (implied) {
destination.setIncludeSubclasses(false);
}
fromClause.addCollectionJoinFromElementByPath(path, destination);
// origin.addDestination(destination);
// Add the query spaces.
fromClause.getWalker().addQuerySpaces(entityPersister.getQuerySpaces());
CollectionType type = queryableCollection.getCollectionType();
String role = type.getRole();
String roleAlias = origin.getTableAlias();
String[] targetColumns = sfh.getCollectionElementColumns(role, roleAlias);
AssociationType elementAssociationType = sfh.getElementAssociationType(type);
// Create the join element under the from element.
JoinType joinType = JoinType.INNER_JOIN;
JoinSequence joinSequence = sfh.createJoinSequence(implied, elementAssociationType, tableAlias, joinType, targetColumns);
elem = initializeJoin(path, destination, joinSequence, targetColumns, origin, false);
// The associated entity is implied, but it must be included in the FROM.
elem.setUseFromFragment(true);
// The collection alias is the role.
elem.setCollectionTableAlias(roleAlias);
return elem;
}
use of org.hibernate.persister.entity.EntityPersister in project hibernate-orm by hibernate.
the class EntityReferenceInitializerImpl method loadFromResultSet.
private void loadFromResultSet(ResultSet resultSet, ResultSetProcessingContext context, Object entityInstance, String concreteEntityTypeName, EntityKey entityKey, LockMode lockModeToAcquire) {
final Serializable id = entityKey.getIdentifier();
// Get the persister for the _subclass_
final Loadable concreteEntityPersister = (Loadable) context.getSession().getFactory().getMetamodel().entityPersister(concreteEntityTypeName);
if (log.isTraceEnabled()) {
log.tracev("Initializing object from ResultSet: {0}", MessageHelper.infoString(concreteEntityPersister, id, context.getSession().getFactory()));
}
// add temp entry so that the next step is circular-reference
// safe - only needed because some types don't take proper
// advantage of two-phase-load (esp. components)
TwoPhaseLoad.addUninitializedEntity(entityKey, entityInstance, concreteEntityPersister, lockModeToAcquire, context.getSession());
final EntityPersister rootEntityPersister = context.getSession().getFactory().getMetamodel().entityPersister(concreteEntityPersister.getRootEntityName());
final Object[] values;
try {
values = concreteEntityPersister.hydrate(resultSet, id, entityInstance, (Loadable) entityReference.getEntityPersister(), concreteEntityPersister == rootEntityPersister ? entityReferenceAliases.getColumnAliases().getSuffixedPropertyAliases() : entityReferenceAliases.getColumnAliases().getSuffixedPropertyAliases(concreteEntityPersister), context.getLoadPlan().areLazyAttributesForceFetched(), context.getSession());
context.getProcessingState(entityReference).registerHydratedState(values);
} catch (SQLException e) {
throw context.getSession().getFactory().getServiceRegistry().getService(JdbcServices.class).getSqlExceptionHelper().convert(e, "Could not read entity state from ResultSet : " + entityKey);
}
final Object rowId;
try {
rowId = concreteEntityPersister.hasRowId() ? resultSet.getObject(entityReferenceAliases.getColumnAliases().getRowIdAlias()) : null;
} catch (SQLException e) {
throw context.getSession().getFactory().getServiceRegistry().getService(JdbcServices.class).getSqlExceptionHelper().convert(e, "Could not read entity row-id from ResultSet : " + entityKey);
}
final EntityType entityType = EntityFetch.class.isInstance(entityReference) ? ((EntityFetch) entityReference).getFetchedType() : entityReference.getEntityPersister().getEntityMetamodel().getEntityType();
if (entityType != null) {
String ukName = entityType.getRHSUniqueKeyPropertyName();
if (ukName != null) {
final int index = ((UniqueKeyLoadable) concreteEntityPersister).getPropertyIndex(ukName);
final Type type = concreteEntityPersister.getPropertyTypes()[index];
// polymorphism not really handled completely correctly,
// perhaps...well, actually its ok, assuming that the
// entity name used in the lookup is the same as the
// the one used here, which it will be
EntityUniqueKey euk = new EntityUniqueKey(entityReference.getEntityPersister().getEntityName(), ukName, type.semiResolve(values[index], context.getSession(), entityInstance), type, concreteEntityPersister.getEntityMode(), context.getSession().getFactory());
context.getSession().getPersistenceContext().addEntity(euk, entityInstance);
}
}
TwoPhaseLoad.postHydrate(concreteEntityPersister, id, values, rowId, entityInstance, lockModeToAcquire, context.getSession());
context.registerHydratedEntity(entityReference, entityKey, entityInstance);
}
use of org.hibernate.persister.entity.EntityPersister in project hibernate-orm by hibernate.
the class AbstractCollectionReference method buildIndexGraph.
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;
}
Aggregations