use of org.hibernate.persister.collection.CollectionPersister in project hibernate-orm by hibernate.
the class JoinWalker method initPersisters.
protected void initPersisters(final List associations, final LockOptions lockOptions, final AssociationInitCallback callback) throws MappingException {
final int joins = countEntityPersisters(associations);
final int collections = countCollectionPersisters(associations);
collectionOwners = collections == 0 ? null : new int[collections];
collectionPersisters = collections == 0 ? null : new CollectionPersister[collections];
collectionSuffixes = BasicLoader.generateSuffixes(joins + 1, collections);
this.lockOptions = lockOptions;
persisters = new Loadable[joins];
aliases = new String[joins];
owners = new int[joins];
ownerAssociationTypes = new EntityType[joins];
lockModeArray = ArrayHelper.fillArray(lockOptions.getLockMode(), joins);
int i = 0;
int j = 0;
for (Object association : associations) {
final OuterJoinableAssociation oj = (OuterJoinableAssociation) association;
if (!oj.isCollection()) {
persisters[i] = (Loadable) oj.getJoinable();
aliases[i] = oj.getRHSAlias();
owners[i] = oj.getOwner(associations);
ownerAssociationTypes[i] = (EntityType) oj.getJoinableType();
callback.associationProcessed(oj, i);
i++;
} else {
QueryableCollection collPersister = (QueryableCollection) oj.getJoinable();
if (oj.getJoinType() == JoinType.LEFT_OUTER_JOIN && !oj.hasRestriction()) {
//it must be a collection fetch
collectionPersisters[j] = collPersister;
collectionOwners[j] = oj.getOwner(associations);
j++;
}
if (collPersister.isOneToMany()) {
persisters[i] = (Loadable) collPersister.getElementPersister();
aliases[i] = oj.getRHSAlias();
callback.associationProcessed(oj, i);
i++;
}
}
}
if (ArrayHelper.isAllNegative(owners)) {
owners = null;
}
if (collectionOwners != null && ArrayHelper.isAllNegative(collectionOwners)) {
collectionOwners = null;
}
}
use of org.hibernate.persister.collection.CollectionPersister in project hibernate-orm by hibernate.
the class CollectionUpdateAction method execute.
@Override
public void execute() throws HibernateException {
final Serializable id = getKey();
final SharedSessionContractImplementor session = getSession();
final CollectionPersister persister = getPersister();
final PersistentCollection collection = getCollection();
final boolean affectedByFilters = persister.isAffectedByEnabledFilters(session);
preUpdate();
if (!collection.wasInitialized()) {
if (!collection.hasQueuedOperations()) {
throw new AssertionFailure("no queued adds");
}
//do nothing - we only need to notify the cache...
} else if (!affectedByFilters && collection.empty()) {
if (!emptySnapshot) {
persister.remove(id, session);
}
} else if (collection.needsRecreate(persister)) {
if (affectedByFilters) {
throw new HibernateException("cannot recreate collection while filter is enabled: " + MessageHelper.collectionInfoString(persister, collection, id, session));
}
if (!emptySnapshot) {
persister.remove(id, session);
}
persister.recreate(collection, id, session);
} else {
persister.deleteRows(collection, id, session);
persister.updateRows(collection, id, session);
persister.insertRows(collection, id, session);
}
getSession().getPersistenceContext().getCollectionEntry(collection).afterAction(collection);
evict();
postUpdate();
if (getSession().getFactory().getStatistics().isStatisticsEnabled()) {
getSession().getFactory().getStatistics().updateCollection(getPersister().getRole());
}
}
use of org.hibernate.persister.collection.CollectionPersister 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.persister.collection.CollectionPersister in project hibernate-orm by hibernate.
the class AbstractEntityPersister method initializeLazyProperty.
public Object initializeLazyProperty(String fieldName, Object entity, SharedSessionContractImplementor session) {
final EntityEntry entry = session.getPersistenceContext().getEntry(entity);
final InterceptorImplementor interceptor = ((PersistentAttributeInterceptable) entity).$$_hibernate_getInterceptor();
assert interceptor != null : "Expecting bytecode interceptor to be non-null";
if (hasCollections()) {
final Type type = getPropertyType(fieldName);
if (type.isCollectionType()) {
// we have a condition where a collection attribute is being access via enhancement:
// we can circumvent all the rest and just return the PersistentCollection
final CollectionType collectionType = (CollectionType) type;
final CollectionPersister persister = factory.getMetamodel().collectionPersister(collectionType.getRole());
// Get/create the collection, and make sure it is initialized! This initialized part is
// different from proxy-based scenarios where we have to create the PersistentCollection
// reference "ahead of time" to add as a reference to the proxy. For bytecode solutions
// we are not creating the PersistentCollection ahead of time, but instead we are creating
// it on first request through the enhanced entity.
// see if there is already a collection instance associated with the session
// NOTE : can this ever happen?
final Serializable key = getCollectionKey(persister, entity, entry, session);
PersistentCollection collection = session.getPersistenceContext().getCollection(new CollectionKey(persister, key));
if (collection == null) {
collection = collectionType.instantiate(session, persister, key);
collection.setOwner(entity);
session.getPersistenceContext().addUninitializedCollection(persister, collection, key);
}
// HHH-11161 Initialize, if the collection is not extra lazy
if (!persister.isExtraLazy()) {
session.initializeCollection(collection, false);
}
interceptor.attributeInitialized(fieldName);
if (collectionType.isArrayType()) {
session.getPersistenceContext().addCollectionHolder(collection);
}
// update the "state" of the entity's EntityEntry to over-write UNFETCHED_PROPERTY reference
// for the collection to the just loaded collection
final EntityEntry ownerEntry = session.getPersistenceContext().getEntry(entity);
if (ownerEntry == null) {
// not good
throw new AssertionFailure("Could not locate EntityEntry for the collection owner in the PersistenceContext");
}
ownerEntry.overwriteLoadedStateCollectionValue(fieldName, collection);
// EARLY EXIT!!!
return collection;
}
}
final Serializable id = session.getContextEntityIdentifier(entity);
if (entry == null) {
throw new HibernateException("entity is not associated with the session: " + id);
}
if (LOG.isTraceEnabled()) {
LOG.tracev("Initializing lazy properties of: {0}, field access: {1}", MessageHelper.infoString(this, id, getFactory()), fieldName);
}
if (session.getCacheMode().isGetEnabled() && hasCache() && isLazyPropertiesCacheable()) {
final EntityRegionAccessStrategy cache = getCacheAccessStrategy();
final Object cacheKey = cache.generateCacheKey(id, this, session.getFactory(), session.getTenantIdentifier());
final Object ce = CacheHelper.fromSharedCache(session, cacheKey, cache);
if (ce != null) {
final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory);
final Object initializedValue = initializeLazyPropertiesFromCache(fieldName, entity, session, entry, cacheEntry);
interceptor.attributeInitialized(fieldName);
// NOTE EARLY EXIT!!!
return initializedValue;
}
}
return initializeLazyPropertiesFromDatastore(fieldName, entity, session, id, entry);
}
use of org.hibernate.persister.collection.CollectionPersister in project hibernate-orm by hibernate.
the class CustomLoader method determineAppropriateOwnerPersister.
private Queryable determineAppropriateOwnerPersister(NonScalarReturn ownerDescriptor) {
String entityName = null;
if (ownerDescriptor instanceof RootReturn) {
entityName = ((RootReturn) ownerDescriptor).getEntityName();
} else if (ownerDescriptor instanceof CollectionReturn) {
CollectionReturn collRtn = (CollectionReturn) ownerDescriptor;
String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
CollectionPersister persister = getFactory().getMetamodel().collectionPersister(role);
EntityType ownerType = (EntityType) persister.getElementType();
entityName = ownerType.getAssociatedEntityName(getFactory());
} else if (ownerDescriptor instanceof FetchReturn) {
FetchReturn fetchRtn = (FetchReturn) ownerDescriptor;
Queryable persister = determineAppropriateOwnerPersister(fetchRtn.getOwner());
Type ownerType = persister.getPropertyType(fetchRtn.getOwnerProperty());
if (ownerType.isEntityType()) {
entityName = ((EntityType) ownerType).getAssociatedEntityName(getFactory());
} else if (ownerType.isCollectionType()) {
Type ownerCollectionElementType = ((CollectionType) ownerType).getElementType(getFactory());
if (ownerCollectionElementType.isEntityType()) {
entityName = ((EntityType) ownerCollectionElementType).getAssociatedEntityName(getFactory());
}
}
}
if (entityName == null) {
throw new HibernateException("Could not determine fetch owner : " + ownerDescriptor);
}
return (Queryable) getFactory().getMetamodel().entityPersister(entityName);
}
Aggregations