use of org.hibernate.event.spi.EventSource in project hibernate-orm by hibernate.
the class DefaultEvictEventListener method onEvict.
/**
* Handle the given evict event.
*
* @param event The evict event to be handled.
*
* @throws HibernateException
*/
public void onEvict(EvictEvent event) throws HibernateException {
final Object object = event.getObject();
if (object == null) {
throw new NullPointerException("null passed to Session.evict()");
}
final EventSource source = event.getSession();
final PersistenceContext persistenceContext = source.getPersistenceContext();
if (object instanceof HibernateProxy) {
final LazyInitializer li = ((HibernateProxy) object).getHibernateLazyInitializer();
final Serializable id = li.getIdentifier();
if (id == null) {
throw new IllegalArgumentException("Could not determine identifier of proxy passed to evict()");
}
final EntityPersister persister = source.getFactory().getEntityPersister(li.getEntityName());
final EntityKey key = source.generateEntityKey(id, persister);
persistenceContext.removeProxy(key);
if (!li.isUninitialized()) {
final Object entity = persistenceContext.removeEntity(key);
if (entity != null) {
EntityEntry e = persistenceContext.removeEntry(entity);
doEvict(entity, key, e.getPersister(), event.getSession());
}
}
li.unsetSession();
} else {
EntityEntry e = persistenceContext.removeEntry(object);
if (e != null) {
persistenceContext.removeEntity(e.getEntityKey());
doEvict(object, e.getEntityKey(), e.getPersister(), source);
} else {
// see if the passed object is even an entity, and if not throw an exception
// this is different than legacy Hibernate behavior, but what JPA 2.1 is calling for
// with EntityManager.detach
EntityPersister persister = null;
final String entityName = persistenceContext.getSession().guessEntityName(object);
if (entityName != null) {
try {
persister = persistenceContext.getSession().getFactory().getEntityPersister(entityName);
} catch (Exception ignore) {
}
}
if (persister == null) {
throw new IllegalArgumentException("Non-entity object instance passed to evict : " + object);
}
}
}
}
use of org.hibernate.event.spi.EventSource in project hibernate-orm by hibernate.
the class DefaultFlushEntityEventListener method scheduleUpdate.
private boolean scheduleUpdate(final FlushEntityEvent event) {
final EntityEntry entry = event.getEntityEntry();
final EventSource session = event.getSession();
final Object entity = event.getEntity();
final Status status = entry.getStatus();
final EntityPersister persister = entry.getPersister();
final Object[] values = event.getPropertyValues();
if (LOG.isTraceEnabled()) {
if (status == Status.DELETED) {
if (!persister.isMutable()) {
LOG.tracev("Updating immutable, deleted entity: {0}", MessageHelper.infoString(persister, entry.getId(), session.getFactory()));
} else if (!entry.isModifiableEntity()) {
LOG.tracev("Updating non-modifiable, deleted entity: {0}", MessageHelper.infoString(persister, entry.getId(), session.getFactory()));
} else {
LOG.tracev("Updating deleted entity: ", MessageHelper.infoString(persister, entry.getId(), session.getFactory()));
}
} else {
LOG.tracev("Updating entity: {0}", MessageHelper.infoString(persister, entry.getId(), session.getFactory()));
}
}
final boolean intercepted = !entry.isBeingReplicated() && handleInterception(event);
// increment the version number (if necessary)
final Object nextVersion = getNextVersion(event);
// if it was dirtied by a collection only
int[] dirtyProperties = event.getDirtyProperties();
if (event.isDirtyCheckPossible() && dirtyProperties == null) {
if (!intercepted && !event.hasDirtyCollection()) {
throw new AssertionFailure("dirty, but no dirty properties");
}
dirtyProperties = ArrayHelper.EMPTY_INT_ARRAY;
}
// check nullability but do not doAfterTransactionCompletion command execute
// we'll use scheduled updates for that.
new Nullability(session).checkNullability(values, persister, true);
// schedule the update
// note that we intentionally do _not_ pass in currentPersistentState!
session.getActionQueue().addAction(new EntityUpdateAction(entry.getId(), values, dirtyProperties, event.hasDirtyCollection(), (status == Status.DELETED && !entry.isModifiableEntity() ? persister.getPropertyValues(entity) : entry.getLoadedState()), entry.getVersion(), nextVersion, entity, entry.getRowId(), persister, session));
return intercepted;
}
use of org.hibernate.event.spi.EventSource in project hibernate-orm by hibernate.
the class DefaultFlushEntityEventListener method onFlushEntity.
/**
* Flushes a single entity's state to the database, by scheduling
* an update action, if necessary
*/
public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
final Object entity = event.getEntity();
final EntityEntry entry = event.getEntityEntry();
final EventSource session = event.getSession();
final EntityPersister persister = entry.getPersister();
final Status status = entry.getStatus();
final Type[] types = persister.getPropertyTypes();
final boolean mightBeDirty = entry.requiresDirtyCheck(entity);
final Object[] values = getValues(entity, entry, mightBeDirty, session);
event.setPropertyValues(values);
//TODO: avoid this for non-new instances where mightBeDirty==false
boolean substitute = wrapCollections(session, persister, types, values);
if (isUpdateNecessary(event, mightBeDirty)) {
substitute = scheduleUpdate(event) || substitute;
}
if (status != Status.DELETED) {
// now update the object .. has to be outside the main if block above (because of collections)
if (substitute) {
persister.setPropertyValues(entity, values);
}
// We don't want to touch collections reachable from a deleted object
if (persister.hasCollections()) {
new FlushVisitor(session, entity).processEntityPropertyValues(values, types);
}
}
}
use of org.hibernate.event.spi.EventSource in project hibernate-orm by hibernate.
the class DefaultFlushEventListener method onFlush.
/** Handle the given flush event.
*
* @param event The flush event to be handled.
* @throws HibernateException
*/
public void onFlush(FlushEvent event) throws HibernateException {
final EventSource source = event.getSession();
final PersistenceContext persistenceContext = source.getPersistenceContext();
if (persistenceContext.getNumberOfManagedEntities() > 0 || persistenceContext.getCollectionEntries().size() > 0) {
try {
source.getEventListenerManager().flushStart();
flushEverythingToExecutions(event);
performExecutions(source);
postFlush(source);
} finally {
source.getEventListenerManager().flushEnd(event.getNumberOfEntitiesProcessed(), event.getNumberOfCollectionsProcessed());
}
postPostFlush(source);
if (source.getFactory().getStatistics().isStatisticsEnabled()) {
source.getFactory().getStatistics().flush();
}
}
}
use of org.hibernate.event.spi.EventSource in project hibernate-orm by hibernate.
the class DefaultMergeEventListener method onMerge.
/**
* Handle the given merge event.
*
* @param event The merge event to be handled.
*
* @throws HibernateException
*/
public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException {
final MergeContext copyCache = (MergeContext) copiedAlready;
final EventSource source = event.getSession();
final Object original = event.getOriginal();
if (original != null) {
final Object entity;
if (original instanceof HibernateProxy) {
LazyInitializer li = ((HibernateProxy) original).getHibernateLazyInitializer();
if (li.isUninitialized()) {
LOG.trace("Ignoring uninitialized proxy");
event.setResult(source.load(li.getEntityName(), li.getIdentifier()));
//EARLY EXIT!
return;
} else {
entity = li.getImplementation();
}
} else {
entity = original;
}
if (copyCache.containsKey(entity) && (copyCache.isOperatedOn(entity))) {
LOG.trace("Already in merge process");
event.setResult(entity);
} else {
if (copyCache.containsKey(entity)) {
LOG.trace("Already in copyCache; setting in merge process");
copyCache.setOperatedOn(entity, true);
}
event.setEntity(entity);
EntityState entityState = null;
// Check the persistence context for an entry relating to this
// entity to be merged...
EntityEntry entry = source.getPersistenceContext().getEntry(entity);
if (entry == null) {
EntityPersister persister = source.getEntityPersister(event.getEntityName(), entity);
Serializable id = persister.getIdentifier(entity, source);
if (id != null) {
final EntityKey key = source.generateEntityKey(id, persister);
final Object managedEntity = source.getPersistenceContext().getEntity(key);
entry = source.getPersistenceContext().getEntry(managedEntity);
if (entry != null) {
// we have specialized case of a detached entity from the
// perspective of the merge operation. Specifically, we
// have an incoming entity instance which has a corresponding
// entry in the current persistence context, but registered
// under a different entity instance
entityState = EntityState.DETACHED;
}
}
}
if (entityState == null) {
entityState = getEntityState(entity, event.getEntityName(), entry, source);
}
switch(entityState) {
case DETACHED:
entityIsDetached(event, copyCache);
break;
case TRANSIENT:
entityIsTransient(event, copyCache);
break;
case PERSISTENT:
entityIsPersistent(event, copyCache);
break;
default:
//DELETED
throw new ObjectDeletedException("deleted instance passed to merge", null, getLoggableName(event.getEntityName(), entity));
}
}
}
}
Aggregations