use of org.hibernate.type.AssociationType in project hibernate-orm by hibernate.
the class CompositionSingularSubAttributesHelper method getSingularSubAttributes.
private static Iterable<AttributeDefinition> getSingularSubAttributes(final AttributeSource source, final OuterJoinLoadable ownerEntityPersister, final CompositeType compositeType, final String lhsTableName, final String[] lhsColumns) {
return new Iterable<AttributeDefinition>() {
@Override
public Iterator<AttributeDefinition> iterator() {
return new Iterator<AttributeDefinition>() {
private final int numberOfAttributes = compositeType.getSubtypes().length;
private int currentSubAttributeNumber;
private int currentColumnPosition;
@Override
public boolean hasNext() {
return currentSubAttributeNumber < numberOfAttributes;
}
@Override
public AttributeDefinition next() {
final int subAttributeNumber = currentSubAttributeNumber;
currentSubAttributeNumber++;
final String name = compositeType.getPropertyNames()[subAttributeNumber];
final Type type = compositeType.getSubtypes()[subAttributeNumber];
final int columnPosition = currentColumnPosition;
final int columnSpan = type.getColumnSpan(ownerEntityPersister.getFactory());
final String[] subAttributeLhsColumns = ArrayHelper.slice(lhsColumns, columnPosition, columnSpan);
final boolean[] propertyNullability = compositeType.getPropertyNullability();
final boolean nullable = propertyNullability == null || propertyNullability[subAttributeNumber];
currentColumnPosition += columnSpan;
if (type.isAssociationType()) {
final AssociationType aType = (AssociationType) type;
return new AssociationAttributeDefinition() {
@Override
public AssociationKey getAssociationKey() {
return new AssociationKey(lhsTableName, subAttributeLhsColumns);
}
@Override
public AssociationNature getAssociationNature() {
if (type.isAnyType()) {
return AssociationNature.ANY;
} else {
// cannot be a collection
return AssociationNature.ENTITY;
}
}
@Override
public EntityDefinition toEntityDefinition() {
if (getAssociationNature() != AssociationNature.ENTITY) {
throw new WalkingException("Cannot build EntityDefinition from non-entity-typed attribute");
}
return (EntityPersister) aType.getAssociatedJoinable(ownerEntityPersister.getFactory());
}
@Override
public AnyMappingDefinition toAnyDefinition() {
if (getAssociationNature() != AssociationNature.ANY) {
throw new WalkingException("Cannot build AnyMappingDefinition from non-any-typed attribute");
}
// todo : not sure how lazy is propogated into the component for a subattribute of type any
return new StandardAnyTypeDefinition((AnyType) aType, false);
}
@Override
public CollectionDefinition toCollectionDefinition() {
throw new WalkingException("A collection cannot be mapped to a composite ID sub-attribute.");
}
@Override
public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath) {
return new FetchStrategy(FetchTiming.IMMEDIATE, FetchStyle.JOIN);
}
@Override
public CascadeStyle determineCascadeStyle() {
return CascadeStyles.NONE;
}
@Override
public HydratedCompoundValueHandler getHydratedCompoundValueExtractor() {
return null;
}
@Override
public String getName() {
return name;
}
@Override
public AssociationType getType() {
return aType;
}
@Override
public boolean isNullable() {
return nullable;
}
@Override
public AttributeSource getSource() {
return source;
}
};
} else if (type.isComponentType()) {
return new CompositionDefinition() {
@Override
public String getName() {
return name;
}
@Override
public CompositeType getType() {
return (CompositeType) type;
}
@Override
public boolean isNullable() {
return nullable;
}
@Override
public AttributeSource getSource() {
return source;
}
@Override
public Iterable<AttributeDefinition> getAttributes() {
return CompositionSingularSubAttributesHelper.getSingularSubAttributes(this, ownerEntityPersister, (CompositeType) type, lhsTableName, subAttributeLhsColumns);
}
};
} else {
return new AttributeDefinition() {
@Override
public String getName() {
return name;
}
@Override
public Type getType() {
return type;
}
@Override
public boolean isNullable() {
return nullable;
}
@Override
public AttributeSource getSource() {
return source;
}
};
}
}
@Override
public void remove() {
throw new UnsupportedOperationException("Remove operation not supported here");
}
};
}
};
}
use of org.hibernate.type.AssociationType in project hibernate-orm by hibernate.
the class AttributeNodeImpl method internalMakeSubgraph.
@SuppressWarnings("unchecked")
private <X> SubgraphImpl<X> internalMakeSubgraph(Class<X> type) {
if (attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC || attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED) {
throw new IllegalArgumentException(String.format("Attribute [%s] is not of managed type", getAttributeName()));
}
if (attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION) {
throw new IllegalArgumentException(String.format("Collection elements [%s] is not of managed type", getAttributeName()));
}
if (subgraphMap == null) {
subgraphMap = new HashMap<>();
}
final Helper.AttributeSource attributeSource = Helper.resolveAttributeSource(sessionFactory(), managedType);
final AssociationType attributeType = (AssociationType) attributeSource.findType(attribute.getName());
final Joinable joinable = attributeType.getAssociatedJoinable(sessionFactory());
if (joinable.isCollection()) {
final EntityPersister elementEntityPersister = ((QueryableCollection) joinable).getElementPersister();
if (type == null) {
type = elementEntityPersister.getMappedClass();
} else {
if (!isTreatableAs(elementEntityPersister, type)) {
throw new IllegalArgumentException(String.format("Collection elements [%s] cannot be treated as requested type [%s] : %s", getAttributeName(), type.getName(), elementEntityPersister.getMappedClass().getName()));
}
}
} else {
final EntityPersister entityPersister = (EntityPersister) joinable;
if (type == null) {
type = entityPersister.getMappedClass();
} else {
if (!isTreatableAs(entityPersister, type)) {
throw new IllegalArgumentException(String.format("Attribute [%s] cannot be treated as requested type [%s] : %s", getAttributeName(), type.getName(), entityPersister.getMappedClass().getName()));
}
}
}
ManagedType managedType = null;
try {
managedType = sessionFactory.getMetamodel().entity(type.getName());
} catch (IllegalArgumentException e) {
// do nothing
}
if (managedType == null) {
managedType = attribute.getDeclaringType();
}
final SubgraphImpl<X> subgraph = new SubgraphImpl<>(this.sessionFactory, managedType, type);
subgraphMap.put(type, subgraph);
return subgraph;
}
use of org.hibernate.type.AssociationType in project hibernate-orm by hibernate.
the class Loader method loadFromResultSet.
/**
* Hydrate the state an object from the SQL <tt>ResultSet</tt>, into
* an array or "hydrated" values (do not resolve associations yet),
* and pass the hydrates state to the session.
*/
private void loadFromResultSet(final ResultSet rs, final int i, final Object object, final String instanceEntityName, final EntityKey key, final String rowIdAlias, final LockMode lockMode, final Loadable rootPersister, final SharedSessionContractImplementor session) throws SQLException, HibernateException {
final Serializable id = key.getIdentifier();
// Get the persister for the _subclass_
final Loadable persister = (Loadable) getFactory().getEntityPersister(instanceEntityName);
if (LOG.isTraceEnabled()) {
LOG.tracef("Initializing object from ResultSet: %s", MessageHelper.infoString(persister, id, getFactory()));
}
boolean fetchAllPropertiesRequested = isEagerPropertyFetchEnabled(i);
// 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(key, object, persister, lockMode, session);
//This is not very nice (and quite slow):
final String[][] cols = persister == rootPersister ? getEntityAliases()[i].getSuffixedPropertyAliases() : getEntityAliases()[i].getSuffixedPropertyAliases(persister);
final Object[] values = persister.hydrate(rs, id, object, rootPersister, cols, fetchAllPropertiesRequested, session);
final Object rowId = persister.hasRowId() ? rs.getObject(rowIdAlias) : null;
final AssociationType[] ownerAssociationTypes = getOwnerAssociationTypes();
if (ownerAssociationTypes != null && ownerAssociationTypes[i] != null) {
String ukName = ownerAssociationTypes[i].getRHSUniqueKeyPropertyName();
if (ukName != null) {
final int index = ((UniqueKeyLoadable) persister).getPropertyIndex(ukName);
final Type type = persister.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(//polymorphism comment above
rootPersister.getEntityName(), ukName, type.semiResolve(values[index], session, object), type, persister.getEntityMode(), session.getFactory());
session.getPersistenceContext().addEntity(euk, object);
}
}
TwoPhaseLoad.postHydrate(persister, id, values, rowId, object, lockMode, session);
}
use of org.hibernate.type.AssociationType in project hibernate-orm by hibernate.
the class JoinWalker method walkCollectionTree.
/**
* For a collection role, return a list of associations to be fetched by outerjoin
*/
private void walkCollectionTree(final QueryableCollection persister, final String alias, final PropertyPath path, final int currentDepth) throws MappingException {
if (persister.isOneToMany()) {
walkEntityTree((OuterJoinLoadable) persister.getElementPersister(), alias, path, currentDepth);
} else {
Type type = persister.getElementType();
if (type.isAssociationType()) {
// a many-to-many;
// decrement currentDepth here to allow join across the association table
// without exceeding MAX_FETCH_DEPTH (i.e. the "currentDepth - 1" bit)
AssociationType associationType = (AssociationType) type;
String[] aliasedLhsColumns = persister.getElementColumnNames(alias);
String[] lhsColumns = persister.getElementColumnNames();
// if the current depth is 0, the root thing being loaded is the
// many-to-many collection itself. Here, it is alright to use
// an inner join...
boolean useInnerJoin = currentDepth == 0;
final JoinType joinType = getJoinType(associationType, persister.getFetchMode(), path, persister.getTableName(), lhsColumns, !useInnerJoin, currentDepth - 1, //operations which cascade as far as the collection also cascade to collection elements
null);
addAssociationToJoinTreeIfNecessary(associationType, aliasedLhsColumns, alias, path, currentDepth - 1, joinType);
} else if (type.isComponentType()) {
walkCompositeElementTree((CompositeType) type, persister.getElementColumnNames(), persister, alias, path, currentDepth);
}
}
}
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);
}
}
}
}
Aggregations