use of org.hibernate.persister.collection.QueryableCollection in project hibernate-orm by hibernate.
the class PathExpressionParser method dereferenceCollection.
private void dereferenceCollection(String propertyName, String role, QueryTranslatorImpl q) throws QueryException {
collectionRole = role;
QueryableCollection collPersister = q.getCollectionPersister(role);
String name = q.createNameForCollection(role);
addJoin(name, collPersister.getCollectionType());
//if ( collPersister.hasWhere() ) join.addCondition( collPersister.getSQLWhereString(name) );
collectionName = name;
collectionOwnerName = currentName;
currentName = name;
currentProperty = propertyName;
componentPath.setLength(0);
currentPropertyMapping = new CollectionPropertyMapping(collPersister);
}
use of org.hibernate.persister.collection.QueryableCollection in project hibernate-orm by hibernate.
the class QueryTranslatorImpl method addFromAssociation.
/**
* Used for collection filters
*/
private void addFromAssociation(final String elementName, final String collectionRole) throws QueryException {
//q.addCollection(collectionName, collectionRole);
QueryableCollection persister = getCollectionPersister(collectionRole);
Type collectionElementType = persister.getElementType();
if (!collectionElementType.isEntityType()) {
throw new QueryException("collection of values in filter: " + elementName);
}
String[] keyColumnNames = persister.getKeyColumnNames();
//if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole);
String collectionName;
JoinSequence join = new JoinSequence(getFactory());
collectionName = persister.isOneToMany() ? elementName : createNameForCollection(collectionRole);
join.setRoot(persister, collectionName);
if (!persister.isOneToMany()) {
//many-to-many
addCollection(collectionName, collectionRole);
try {
join.addJoin((AssociationType) persister.getElementType(), elementName, JoinType.INNER_JOIN, persister.getElementColumnNames(collectionName));
} catch (MappingException me) {
throw new QueryException(me);
}
}
join.addCondition(collectionName, keyColumnNames, " = ?");
//if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) );
EntityType elemType = (EntityType) collectionElementType;
addFrom(elementName, elemType.getAssociatedEntityName(), join);
}
use of org.hibernate.persister.collection.QueryableCollection in project hibernate-orm by hibernate.
the class IndexNode method resolve.
@Override
public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent, AST parentPredicate) throws SemanticException {
if (isResolved()) {
return;
}
FromReferenceNode collectionNode = (FromReferenceNode) getFirstChild();
SessionFactoryHelper sessionFactoryHelper = getSessionFactoryHelper();
// Fully resolve the map reference, create implicit joins.
collectionNode.resolveIndex(this);
Type type = collectionNode.getDataType();
if (!type.isCollectionType()) {
throw new SemanticException("The [] operator cannot be applied to type " + type.toString());
}
String collectionRole = ((CollectionType) type).getRole();
QueryableCollection queryableCollection = sessionFactoryHelper.requireQueryableCollection(collectionRole);
if (!queryableCollection.hasIndex()) {
throw new QueryException("unindexed fromElement beforeQuery []: " + collectionNode.getPath());
}
// Generate the inner join -- The elements need to be joined to the collection they are in.
FromElement fromElement = collectionNode.getFromElement();
String elementTable = fromElement.getTableAlias();
FromClause fromClause = fromElement.getFromClause();
String path = collectionNode.getPath();
FromElement elem = fromClause.findCollectionJoin(path);
if (elem == null) {
FromElementFactory factory = new FromElementFactory(fromClause, fromElement, path);
elem = factory.createCollectionElementsJoin(queryableCollection, elementTable);
LOG.debugf("No FROM element found for the elements of collection join path %s, created %s", path, elem);
} else {
LOG.debugf("FROM element found for collection join path %s", path);
}
// The 'from element' that represents the elements of the collection.
setFromElement(fromElement);
// Add the condition to the join sequence that qualifies the indexed element.
AST selector = collectionNode.getNextSibling();
if (selector == null) {
throw new QueryException("No index value!");
}
// Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many)
String collectionTableAlias = elementTable;
if (elem.getCollectionTableAlias() != null) {
collectionTableAlias = elem.getCollectionTableAlias();
}
// TODO: get SQL rendering out of here, create an AST for the join expressions.
// Use the SQL generator grammar to generate the SQL text for the index expression.
JoinSequence joinSequence = fromElement.getJoinSequence();
String[] indexCols = queryableCollection.getIndexColumnNames();
if (indexCols.length != 1) {
throw new QueryException("composite-index appears in []: " + collectionNode.getPath());
}
SqlGenerator gen = new SqlGenerator(getSessionFactoryHelper().getFactory());
try {
//TODO: used to be exprNoParens! was this needed?
gen.simpleExpr(selector);
} catch (RecognitionException e) {
throw new QueryException(e.getMessage(), e);
}
String selectorExpression = gen.getSQL();
joinSequence.addCondition(collectionTableAlias + '.' + indexCols[0] + " = " + selectorExpression);
List<ParameterSpecification> paramSpecs = gen.getCollectedParameters();
if (paramSpecs != null) {
switch(paramSpecs.size()) {
case 0:
// nothing to do
break;
case 1:
ParameterSpecification paramSpec = paramSpecs.get(0);
paramSpec.setExpectedType(queryableCollection.getIndexType());
fromElement.setIndexCollectionSelectorParamSpec(paramSpec);
break;
default:
fromElement.setIndexCollectionSelectorParamSpec(new AggregatedIndexCollectionSelectorParameterSpecifications(paramSpecs));
break;
}
}
// Now, set the text for this node. It should be the element columns.
String[] elementColumns = queryableCollection.getElementColumnNames(elementTable);
setText(elementColumns[0]);
setResolved();
}
use of org.hibernate.persister.collection.QueryableCollection in project hibernate-orm by hibernate.
the class IndexNode method prepareForDot.
@Override
public void prepareForDot(String propertyName) throws SemanticException {
FromElement fromElement = getFromElement();
if (fromElement == null) {
throw new IllegalStateException("No FROM element for index operator!");
}
final QueryableCollection queryableCollection = fromElement.getQueryableCollection();
if (queryableCollection != null && !queryableCollection.isOneToMany()) {
final FromReferenceNode collectionNode = (FromReferenceNode) getFirstChild();
final String path = collectionNode.getPath() + "[]." + propertyName;
LOG.debugf("Creating join for many-to-many elements for %s", path);
final FromElementFactory factory = new FromElementFactory(fromElement.getFromClause(), fromElement, path);
// This will add the new from element to the origin.
final FromElement elementJoin = factory.createElementJoin(queryableCollection);
setFromElement(elementJoin);
}
}
use of org.hibernate.persister.collection.QueryableCollection in project hibernate-orm by hibernate.
the class AbstractMapComponentNode method resolve.
@Override
public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent, AST parentPredicate) throws SemanticException {
if (mapFromElement == null) {
final FromReferenceNode mapReference = getMapReference();
mapReference.resolve(true, true);
FromElement sourceFromElement = null;
if (isAliasRef(mapReference)) {
final QueryableCollection collectionPersister = mapReference.getFromElement().getQueryableCollection();
if (Map.class.isAssignableFrom(collectionPersister.getCollectionType().getReturnedClass())) {
sourceFromElement = mapReference.getFromElement();
}
} else {
if (mapReference.getDataType().isCollectionType()) {
final CollectionType collectionType = (CollectionType) mapReference.getDataType();
if (Map.class.isAssignableFrom(collectionType.getReturnedClass())) {
sourceFromElement = mapReference.getFromElement();
}
}
}
if (sourceFromElement == null) {
throw nonMap();
}
mapFromElement = sourceFromElement;
}
setFromElement(mapFromElement);
setDataType(resolveType(mapFromElement.getQueryableCollection()));
this.columns = resolveColumns(mapFromElement.getQueryableCollection());
initText(this.columns);
setFirstChild(null);
}
Aggregations