use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class EntityIdentityInsertAction method execute.
@Override
public void execute() throws HibernateException {
nullifyTransientReferencesIfNotAlready();
final EntityPersister persister = getPersister();
final SharedSessionContractImplementor session = getSession();
final Object instance = getInstance();
final boolean veto = preInsert();
if (!veto) {
generatedId = persister.insert(getState(), instance, session);
if (persister.hasInsertGeneratedProperties()) {
persister.processInsertGeneratedProperties(generatedId, instance, getState(), session);
}
//need to do that here rather than in the save event listener to let
//the post insert events to have a id-filled entity when IDENTITY is used (EJB3)
persister.setIdentifier(instance, generatedId, session);
session.getPersistenceContext().registerInsertedKey(getPersister(), generatedId);
entityKey = session.generateEntityKey(generatedId, persister);
session.getPersistenceContext().checkUniqueness(entityKey, getInstance());
}
//TODO: this bit actually has to be called afterQuery all cascades!
// but since identity insert is called *synchronously*,
// instead of asynchronously as other actions, it isn't
/*if ( persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
cacheEntry = new CacheEntry(object, persister, session);
persister.getCache().insert(generatedId, cacheEntry);
}*/
postInsert();
if (session.getFactory().getStatistics().isStatisticsEnabled() && !veto) {
session.getFactory().getStatisticsImplementor().insertEntity(getPersister().getEntityName());
}
markExecuted();
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class Helper method openTemporarySessionForLoading.
private SharedSessionContractImplementor openTemporarySessionForLoading(LazyInitializationWork lazyInitializationWork) {
if (consumer.getSessionFactoryUuid() == null) {
throwLazyInitializationException(Cause.NO_SF_UUID, lazyInitializationWork);
}
final SessionFactoryImplementor sf = (SessionFactoryImplementor) SessionFactoryRegistry.INSTANCE.getSessionFactory(consumer.getSessionFactoryUuid());
final SharedSessionContractImplementor session = (SharedSessionContractImplementor) sf.openSession();
session.getPersistenceContext().setDefaultReadOnly(true);
session.setHibernateFlushMode(FlushMode.MANUAL);
return session;
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class AbstractPersistentCollection method withTemporarySessionIfNeeded.
private <T> T withTemporarySessionIfNeeded(LazyInitializationWork<T> lazyInitializationWork) {
SharedSessionContractImplementor tempSession = null;
if (session == null) {
if (allowLoadOutsideTransaction) {
tempSession = openTemporarySessionForLoading();
} else {
throwLazyInitializationException("could not initialize proxy - no Session");
}
} else if (!session.isOpen()) {
if (allowLoadOutsideTransaction) {
tempSession = openTemporarySessionForLoading();
} else {
throwLazyInitializationException("could not initialize proxy - the owning Session was closed");
}
} else if (!session.isConnected()) {
if (allowLoadOutsideTransaction) {
tempSession = openTemporarySessionForLoading();
} else {
throwLazyInitializationException("could not initialize proxy - the owning Session is disconnected");
}
}
SharedSessionContractImplementor originalSession = null;
boolean isJTA = false;
if (tempSession != null) {
isTempSession = true;
originalSession = session;
session = tempSession;
isJTA = session.getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta();
if (!isJTA) {
// Explicitly handle the transactions only if we're not in
// a JTA environment. A lazy loading temporary session can
// be created even if a current session and transaction are
// open (ex: session.clear() was used). We must prevent
// multiple transactions.
((Session) session).beginTransaction();
}
session.getPersistenceContext().addUninitializedDetachedCollection(session.getFactory().getCollectionPersister(getRole()), this);
}
try {
return lazyInitializationWork.doWork();
} finally {
if (tempSession != null) {
// make sure the just opened temp session gets closed!
isTempSession = false;
session = originalSession;
try {
if (!isJTA) {
((Session) tempSession).getTransaction().commit();
}
((Session) tempSession).close();
} catch (Exception e) {
LOG.warn("Unable to close temporary session used to load lazy collection associated to no session");
}
}
}
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class CollectionLoadContext method addCollectionToCache.
/**
* Add the collection to the second-level cache
*
* @param lce The entry representing the collection to add
* @param persister The persister
*/
private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersister persister) {
final SharedSessionContractImplementor session = getLoadContext().getPersistenceContext().getSession();
final SessionFactoryImplementor factory = session.getFactory();
final boolean debugEnabled = LOG.isDebugEnabled();
if (debugEnabled) {
LOG.debugf("Caching collection: %s", MessageHelper.collectionInfoString(persister, lce.getCollection(), lce.getKey(), session));
}
if (!session.getLoadQueryInfluencers().getEnabledFilters().isEmpty() && persister.isAffectedByEnabledFilters(session)) {
// some filters affecting the collection are enabled on the session, so do not do the put into the cache.
if (debugEnabled) {
LOG.debug("Refusing to add to cache due to enabled filters");
}
// EARLY EXIT!!!!!
return;
}
final Object version;
if (persister.isVersioned()) {
Object collectionOwner = getLoadContext().getPersistenceContext().getCollectionOwner(lce.getKey(), persister);
if (collectionOwner == null) {
// resolution against the PC anyway just to be safe since the lookup should not be costly.
if (lce.getCollection() != null) {
final Object linkedOwner = lce.getCollection().getOwner();
if (linkedOwner != null) {
final Serializable ownerKey = persister.getOwnerEntityPersister().getIdentifier(linkedOwner, session);
collectionOwner = getLoadContext().getPersistenceContext().getCollectionOwner(ownerKey, persister);
}
}
if (collectionOwner == null) {
throw new HibernateException("Unable to resolve owner of loading collection [" + MessageHelper.collectionInfoString(persister, lce.getCollection(), lce.getKey(), session) + "] for second level caching");
}
}
version = getLoadContext().getPersistenceContext().getEntry(collectionOwner).getVersion();
} else {
version = null;
}
final CollectionCacheEntry entry = new CollectionCacheEntry(lce.getCollection(), persister);
final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy();
final Object cacheKey = cache.generateCacheKey(lce.getKey(), persister, session.getFactory(), session.getTenantIdentifier());
boolean isPutFromLoad = true;
if (persister.getElementType().isAssociationType()) {
for (Serializable id : entry.getState()) {
EntityPersister entityPersister = ((QueryableCollection) persister).getElementPersister();
if (session.getPersistenceContext().wasInsertedDuringTransaction(entityPersister, id)) {
isPutFromLoad = false;
break;
}
}
}
// CollectionRegionAccessStrategy has no update, so avoid putting uncommitted data via putFromLoad
if (isPutFromLoad) {
try {
session.getEventListenerManager().cachePutStart();
final boolean put = cache.putFromLoad(session, cacheKey, persister.getCacheEntryStructure().structure(entry), session.getTimestamp(), version, factory.getSessionFactoryOptions().isMinimalPutsEnabled() && session.getCacheMode() != CacheMode.REFRESH);
if (put && factory.getStatistics().isStatisticsEnabled()) {
factory.getStatistics().secondLevelCachePut(persister.getCacheAccessStrategy().getRegion().getName());
}
} finally {
session.getEventListenerManager().cachePutEnd();
}
}
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class DefaultRefreshEventListener method onRefresh.
/**
* Handle the given refresh event.
*
* @param event The refresh event to be handled.
*/
public void onRefresh(RefreshEvent event, Map refreshedAlready) {
final EventSource source = event.getSession();
boolean isTransient;
if (event.getEntityName() != null) {
isTransient = !source.contains(event.getEntityName(), event.getObject());
} else {
isTransient = !source.contains(event.getObject());
}
if (source.getPersistenceContext().reassociateIfUninitializedProxy(event.getObject())) {
if (isTransient) {
source.setReadOnly(event.getObject(), source.isDefaultReadOnly());
}
return;
}
final Object object = source.getPersistenceContext().unproxyAndReassociate(event.getObject());
if (refreshedAlready.containsKey(object)) {
LOG.trace("Already refreshed");
return;
}
final EntityEntry e = source.getPersistenceContext().getEntry(object);
final EntityPersister persister;
final Serializable id;
if (e == null) {
persister = source.getEntityPersister(event.getEntityName(), object);
//refresh() does not pass an entityName
id = persister.getIdentifier(object, event.getSession());
if (LOG.isTraceEnabled()) {
LOG.tracev("Refreshing transient {0}", MessageHelper.infoString(persister, id, source.getFactory()));
}
final EntityKey key = source.generateEntityKey(id, persister);
if (source.getPersistenceContext().getEntry(key) != null) {
throw new PersistentObjectException("attempted to refresh transient instance when persistent instance was already associated with the Session: " + MessageHelper.infoString(persister, id, source.getFactory()));
}
} else {
if (LOG.isTraceEnabled()) {
LOG.tracev("Refreshing ", MessageHelper.infoString(e.getPersister(), e.getId(), source.getFactory()));
}
if (!e.isExistsInDatabase()) {
throw new UnresolvableObjectException(e.getId(), "this instance does not yet exist as a row in the database");
}
persister = e.getPersister();
id = e.getId();
}
// cascade the refresh prior to refreshing this entity
refreshedAlready.put(object, object);
Cascade.cascade(CascadingActions.REFRESH, CascadePoint.BEFORE_REFRESH, source, persister, object, refreshedAlready);
if (e != null) {
final EntityKey key = source.generateEntityKey(id, persister);
source.getPersistenceContext().removeEntity(key);
if (persister.hasCollections()) {
new EvictVisitor(source).process(object, persister);
}
}
if (persister.hasCache()) {
Object previousVersion = null;
if (persister.isVersionPropertyGenerated()) {
// we need to grab the version value from the entity, otherwise
// we have issues with generated-version entities that may have
// multiple actions queued during the same flush
previousVersion = persister.getVersion(object);
}
final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(id, persister, source.getFactory(), source.getTenantIdentifier());
final SoftLock lock = cache.lockItem(source, ck, previousVersion);
source.getActionQueue().registerProcess(new AfterTransactionCompletionProcess() {
@Override
public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) {
cache.unlockItem(session, ck, lock);
}
});
cache.remove(source, ck);
}
evictCachedCollections(persister, id, source);
String previousFetchProfile = source.getLoadQueryInfluencers().getInternalFetchProfile();
source.getLoadQueryInfluencers().setInternalFetchProfile("refresh");
Object result = persister.load(id, object, event.getLockOptions(), source);
// If it was transient, then set it to the default for the source.
if (result != null) {
if (!persister.isMutable()) {
// this is probably redundant; it should already be read-only
source.setReadOnly(result, true);
} else {
source.setReadOnly(result, (e == null ? source.isDefaultReadOnly() : e.isReadOnly()));
}
}
source.getLoadQueryInfluencers().setInternalFetchProfile(previousFetchProfile);
UnresolvableObjectException.throwIfNull(result, id, persister.getEntityName());
}
Aggregations