use of org.hibernate.type.AssociationType in project hibernate-orm by hibernate.
the class JoinWalker method walkEntityTree.
/**
* Walk the association tree for an entity, adding associations which should
* be join fetched to the {@link #associations} inst var. This form is the
* entry point into the walking for a given entity, starting the recursive
* calls into {@link #walkEntityTree(org.hibernate.persister.entity.OuterJoinLoadable, String, PropertyPath, int)}.
*
* @param persister The persister representing the entity to be walked.
* @param alias The (root) alias to use for this entity/persister.
* @param path The property path to the entity being walked
* @param currentDepth The current join depth
*
* @throws org.hibernate.MappingException ???
*/
private void walkEntityTree(final OuterJoinLoadable persister, final String alias, final PropertyPath 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((CompositeType) type, i, 0, persister, alias, path.append(persister.getSubclassPropertyName(i)), currentDepth);
}
}
// if the entity has a composite identifier, see if we need to handle
// its sub-properties separately
final Type idType = persister.getIdentifierType();
if (idType.isComponentType()) {
final CompositeType cidType = (CompositeType) idType;
if (cidType.isEmbedded()) {
// explicitly at odds with the notion of "embedded composite". So we use that for now
if (persister.getEntityMetamodel().getIdentifierProperty().isEmbedded()) {
walkComponentTree(cidType, -1, 0, persister, alias, path, currentDepth);
}
}
}
}
use of org.hibernate.type.AssociationType 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.type.AssociationType in project hibernate-orm by hibernate.
the class MetamodelImpl method initialize.
/**
* Prepare the metamodel using the information from the collection of Hibernate
* {@link PersistentClass} models
*
* @param mappingMetadata The mapping information
* @param jpaMetaModelPopulationSetting Should the JPA Metamodel be built as well?
*/
public void initialize(MetadataImplementor mappingMetadata, JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting) {
this.imports.putAll(mappingMetadata.getImports());
final PersisterCreationContext persisterCreationContext = new PersisterCreationContext() {
@Override
public SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
}
@Override
public MetadataImplementor getMetadata() {
return mappingMetadata;
}
};
final PersisterFactory persisterFactory = sessionFactory.getServiceRegistry().getService(PersisterFactory.class);
for (final PersistentClass model : mappingMetadata.getEntityBindings()) {
final EntityRegionAccessStrategy accessStrategy = sessionFactory.getCache().determineEntityRegionAccessStrategy(model);
final NaturalIdRegionAccessStrategy naturalIdAccessStrategy = sessionFactory.getCache().determineNaturalIdRegionAccessStrategy(model);
final EntityPersister cp = persisterFactory.createEntityPersister(model, accessStrategy, naturalIdAccessStrategy, persisterCreationContext);
entityPersisterMap.put(model.getEntityName(), cp);
if (cp.getConcreteProxyClass() != null && cp.getConcreteProxyClass().isInterface() && !Map.class.isAssignableFrom(cp.getConcreteProxyClass()) && cp.getMappedClass() != cp.getConcreteProxyClass()) {
if (cp.getMappedClass().equals(cp.getConcreteProxyClass())) {
// this part handles an odd case in the Hibernate test suite where we map an interface
// as the class and the proxy. I cannot think of a real life use case for that
// specific test, but..
log.debugf("Entity [%s] mapped same interface [%s] as class and proxy", cp.getEntityName(), cp.getMappedClass());
} else {
final String old = entityProxyInterfaceMap.put(cp.getConcreteProxyClass(), cp.getEntityName());
if (old != null) {
throw new HibernateException(String.format(Locale.ENGLISH, "Multiple entities [%s, %s] named the same interface [%s] as their proxy which is not supported", old, cp.getEntityName(), cp.getConcreteProxyClass().getName()));
}
}
}
}
for (final Collection model : mappingMetadata.getCollectionBindings()) {
final CollectionRegionAccessStrategy accessStrategy = sessionFactory.getCache().determineCollectionRegionAccessStrategy(model);
final CollectionPersister persister = persisterFactory.createCollectionPersister(model, accessStrategy, persisterCreationContext);
collectionPersisterMap.put(model.getRole(), persister);
Type indexType = persister.getIndexType();
if (indexType != null && indexType.isAssociationType() && !indexType.isAnyType()) {
String entityName = ((AssociationType) indexType).getAssociatedEntityName(sessionFactory);
Set<String> roles = collectionRolesByEntityParticipant.get(entityName);
if (roles == null) {
roles = new HashSet<>();
collectionRolesByEntityParticipant.put(entityName, roles);
}
roles.add(persister.getRole());
}
Type elementType = persister.getElementType();
if (elementType.isAssociationType() && !elementType.isAnyType()) {
String entityName = ((AssociationType) elementType).getAssociatedEntityName(sessionFactory);
Set<String> roles = collectionRolesByEntityParticipant.get(entityName);
if (roles == null) {
roles = new HashSet<>();
collectionRolesByEntityParticipant.put(entityName, roles);
}
roles.add(persister.getRole());
}
}
// after *all* persisters and named queries are registered
entityPersisterMap.values().forEach(EntityPersister::generateEntityDefinition);
for (EntityPersister persister : entityPersisterMap.values()) {
persister.postInstantiate();
registerEntityNameResolvers(persister, entityNameResolvers);
}
collectionPersisterMap.values().forEach(CollectionPersister::postInstantiate);
if (jpaMetaModelPopulationSetting != JpaMetaModelPopulationSetting.DISABLED) {
MetadataContext context = new MetadataContext(sessionFactory, mappingMetadata.getMappedSuperclassMappingsCopy(), jpaMetaModelPopulationSetting);
for (PersistentClass entityBinding : mappingMetadata.getEntityBindings()) {
locateOrBuildEntityType(entityBinding, context);
}
handleUnusedMappedSuperclasses(context);
context.wrapUp();
this.jpaEntityTypeMap.putAll(context.getEntityTypeMap());
this.jpaEmbeddableTypeMap.putAll(context.getEmbeddableTypeMap());
this.jpaMappedSuperclassTypeMap.putAll(context.getMappedSuperclassTypeMap());
this.jpaEntityTypesByEntityName.putAll(context.getEntityTypesByEntityName());
applyNamedEntityGraphs(mappingMetadata.getNamedEntityGraphs().values());
}
}
use of org.hibernate.type.AssociationType in project hibernate-orm by hibernate.
the class AbstractEntityPersister method getSubclassPropertyTableNumber.
/**
* Warning:
* When there are duplicated property names in the subclasses
* of the class, this method may return the wrong table
* number for the duplicated subclass property (note that
* SingleTableEntityPersister defines an overloaded form
* which takes the entity name.
*/
public int getSubclassPropertyTableNumber(String propertyPath) {
String rootPropertyName = StringHelper.root(propertyPath);
Type type = propertyMapping.toType(rootPropertyName);
if (type.isAssociationType()) {
AssociationType assocType = (AssociationType) type;
if (assocType.useLHSPrimaryKey()) {
// performance op to avoid the array search
return 0;
} else if (type.isCollectionType()) {
// properly handle property-ref-based associations
rootPropertyName = assocType.getLHSPropertyName();
}
}
//Enable for HHH-440, which we don't like:
/*if ( type.isComponentType() && !propertyName.equals(rootPropertyName) ) {
String unrooted = StringHelper.unroot(propertyName);
int idx = ArrayHelper.indexOf( getSubclassColumnClosure(), unrooted );
if ( idx != -1 ) {
return getSubclassColumnTableNumberClosure()[idx];
}
}*/
int index = ArrayHelper.indexOf(getSubclassPropertyNameClosure(), rootPropertyName);
//TODO: optimize this better!
return index == -1 ? 0 : getSubclassPropertyTableNumber(index);
}
use of org.hibernate.type.AssociationType 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;
}
Aggregations