use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class AbstractPersistentCollection method getOrphans.
/**
* Given a collection of entity instances that used to
* belong to the collection, and a collection of instances
* that currently belong, return a collection of orphans
*/
@SuppressWarnings({ "JavaDoc", "unchecked" })
protected static Collection getOrphans(Collection oldElements, Collection currentElements, String entityName, SharedSessionContractImplementor session) throws HibernateException {
// short-circuit(s)
if (currentElements.size() == 0) {
// no new elements, the old list contains only Orphans
return oldElements;
}
if (oldElements.size() == 0) {
// no old elements, so no Orphans neither
return oldElements;
}
final EntityPersister entityPersister = session.getFactory().getEntityPersister(entityName);
final Type idType = entityPersister.getIdentifierType();
final boolean useIdDirect = mayUseIdDirect(idType);
// create the collection holding the Orphans
final Collection res = new ArrayList();
// collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for fast access
final java.util.Set currentIds = new HashSet();
final java.util.Set currentSaving = new IdentitySet();
for (Object current : currentElements) {
if (current != null && ForeignKeys.isNotTransient(entityName, current, null, session)) {
final EntityEntry ee = session.getPersistenceContext().getEntry(current);
if (ee != null && ee.getStatus() == Status.SAVING) {
currentSaving.add(current);
} else {
final Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, current, session);
currentIds.add(useIdDirect ? currentId : new TypedValue(idType, currentId));
}
}
}
// iterate over the *old* list
for (Object old : oldElements) {
if (!currentSaving.contains(old)) {
final Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, old, session);
if (!currentIds.contains(useIdDirect ? oldId : new TypedValue(idType, oldId))) {
res.add(old);
}
}
}
return res;
}
use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class OptimisticLockingStrategy method lock.
@Override
public void lock(Serializable id, Object version, Object object, int timeout, SharedSessionContractImplementor session) {
if (!lockable.isVersioned()) {
throw new OptimisticLockException(object, "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]");
}
final EntityEntry entry = session.getPersistenceContext().getEntry(object);
// Register the EntityVerifyVersionProcess action to run just prior to transaction commit.
((EventSource) session).getActionQueue().registerProcess(new EntityVerifyVersionProcess(object, entry));
}
use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class AbstractEntityPersister method delete.
/**
* Delete an object
*/
public void delete(Serializable id, Object version, Object object, SharedSessionContractImplementor session) throws HibernateException {
final int span = getTableSpan();
boolean isImpliedOptimisticLocking = !entityMetamodel.isVersioned() && isAllOrDirtyOptLocking();
Object[] loadedState = null;
if (isImpliedOptimisticLocking) {
// need to treat this as if it where optimistic-lock="all" (dirty does *not* make sense);
// first we need to locate the "loaded" state
//
// Note, it potentially could be a proxy, so doAfterTransactionCompletion the location the safe way...
final EntityKey key = session.generateEntityKey(id, this);
Object entity = session.getPersistenceContext().getEntity(key);
if (entity != null) {
EntityEntry entry = session.getPersistenceContext().getEntry(entity);
loadedState = entry.getLoadedState();
}
}
final String[] deleteStrings;
if (isImpliedOptimisticLocking && loadedState != null) {
// we need to utilize dynamic delete statements
deleteStrings = generateSQLDeletStrings(loadedState);
} else {
// otherwise, utilize the static delete statements
deleteStrings = getSQLDeleteStrings();
}
for (int j = span - 1; j >= 0; j--) {
delete(id, version, j, object, deleteStrings[j], session, loadedState);
}
}
use of org.hibernate.engine.spi.EntityEntry 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.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class DynamicBatchingEntityLoaderBuilder method performUnorderedMultiLoad.
@SuppressWarnings("unchecked")
protected List performUnorderedMultiLoad(OuterJoinLoadable persister, Serializable[] ids, SharedSessionContractImplementor session, MultiLoadOptions loadOptions) {
assert !loadOptions.isOrderReturnEnabled();
final List result = CollectionHelper.arrayList(ids.length);
if (loadOptions.isSessionCheckingEnabled()) {
// the user requested that we exclude ids corresponding to already managed
// entities from the generated load SQL. So here we will iterate all
// incoming id values and see whether it corresponds to an existing
// entity associated with the PC - if it does we add it to the result
// list immediately and remove its id from the group of ids to load.
boolean foundAnyManagedEntities = false;
final List<Serializable> nonManagedIds = new ArrayList<Serializable>();
for (Serializable id : ids) {
final EntityKey entityKey = new EntityKey(id, persister);
final Object managedEntity = session.getPersistenceContext().getEntity(entityKey);
if (managedEntity != null) {
if (!loadOptions.isReturnOfDeletedEntitiesEnabled()) {
final EntityEntry entry = session.getPersistenceContext().getEntry(managedEntity);
if (entry.getStatus() == Status.DELETED || entry.getStatus() == Status.GONE) {
continue;
}
}
foundAnyManagedEntities = true;
result.add(managedEntity);
} else {
nonManagedIds.add(id);
}
}
if (foundAnyManagedEntities) {
if (nonManagedIds.isEmpty()) {
// all of the given ids were already associated with the Session
return result;
} else {
// over-write the ids to be loaded with the collection of
// just non-managed ones
ids = nonManagedIds.toArray((Serializable[]) Array.newInstance(ids.getClass().getComponentType(), nonManagedIds.size()));
}
}
}
final LockOptions lockOptions = (loadOptions.getLockOptions() == null) ? new LockOptions(LockMode.NONE) : loadOptions.getLockOptions();
int numberOfIdsLeft = ids.length;
final int maxBatchSize;
if (loadOptions.getBatchSize() != null && loadOptions.getBatchSize() > 0) {
maxBatchSize = loadOptions.getBatchSize();
} else {
maxBatchSize = session.getJdbcServices().getJdbcEnvironment().getDialect().getDefaultBatchLoadSizingStrategy().determineOptimalBatchLoadSize(persister.getIdentifierType().getColumnSpan(session.getFactory()), numberOfIdsLeft);
}
int idPosition = 0;
while (numberOfIdsLeft > 0) {
int batchSize = Math.min(numberOfIdsLeft, maxBatchSize);
final DynamicEntityLoader batchingLoader = new DynamicEntityLoader(persister, batchSize, lockOptions, session.getFactory(), session.getLoadQueryInfluencers());
Serializable[] idsInBatch = new Serializable[batchSize];
System.arraycopy(ids, idPosition, idsInBatch, 0, batchSize);
QueryParameters qp = buildMultiLoadQueryParameters(persister, idsInBatch, lockOptions);
result.addAll(batchingLoader.doEntityBatchFetch(session, qp, idsInBatch));
numberOfIdsLeft = numberOfIdsLeft - batchSize;
idPosition += batchSize;
}
return result;
}
Aggregations