public String addFromCollection(QueryTranslatorImpl q) throws QueryException { Type collectionElementType = getPropertyType(); if (collectionElementType == null) { throw new QueryException( "must specify 'elements' for collection valued property in from clause: " + path); } if (collectionElementType.isEntityType()) { // an association QueryableCollection collectionPersister = q.getCollectionPersister(collectionRole); Queryable entityPersister = (Queryable) collectionPersister.getElementPersister(); String clazz = entityPersister.getEntityName(); final String elementName; if (collectionPersister.isOneToMany()) { elementName = collectionName; // allow index() function: q.decoratePropertyMapping(elementName, collectionPersister); } else { // many-to-many q.addCollection(collectionName, collectionRole); elementName = q.createNameFor(clazz); addJoin(elementName, (AssociationType) collectionElementType); } q.addFrom(elementName, clazz, joinSequence); currentPropertyMapping = new CollectionPropertyMapping(collectionPersister); return elementName; } else { // collections of values q.addFromCollection(collectionName, collectionRole, joinSequence); return collectionName; } }
String continueFromManyToMany(String entityName, String[] joinColumns, QueryTranslatorImpl q) throws QueryException { start(q); continuation = true; currentName = q.createNameFor(entityName); q.addType(currentName, entityName); Queryable classPersister = q.getEntityPersister(entityName); // QueryJoinFragment join = q.createJoinFragment(useThetaStyleJoin); addJoin( currentName, q.getFactory().getTypeResolver().getTypeFactory().manyToOne(entityName), joinColumns); currentPropertyMapping = classPersister; return currentName; }
private void dereferenceEntity( String propertyName, EntityType propertyType, QueryTranslatorImpl q) throws QueryException { // NOTE: we avoid joining to the next table if the named property is just the foreign key value // if its "id" boolean isIdShortcut = EntityPersister.ENTITY_ID.equals(propertyName) && propertyType.isReferenceToPrimaryKey(); // or its the id property name final String idPropertyName; try { idPropertyName = propertyType.getIdentifierOrUniqueKeyPropertyName(q.getFactory()); } catch (MappingException me) { throw new QueryException(me); } boolean isNamedIdPropertyShortcut = idPropertyName != null && idPropertyName.equals(propertyName) && propertyType.isReferenceToPrimaryKey(); if (isIdShortcut || isNamedIdPropertyShortcut) { // special shortcut for id properties, skip the join! // this must only occur at the _end_ of a path expression if (componentPath.length() > 0) componentPath.append('.'); componentPath.append(propertyName); } else { String entityClass = propertyType.getAssociatedEntityName(); String name = q.createNameFor(entityClass); q.addType(name, entityClass); addJoin(name, propertyType); if (propertyType.isOneToOne()) oneToOneOwnerName = currentName; ownerAssociationType = propertyType; currentName = name; currentProperty = propertyName; q.addPathAliasAndJoin( path.substring(0, path.toString().lastIndexOf('.')), name, joinSequence.copy()); componentPath.setLength(0); currentPropertyMapping = q.getEntityPersister(entityClass); } }