![JAR search and dependency download from the Maven repository](/logo.png)
org.hibernate.impl.SessionImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate Show documentation
Show all versions of hibernate Show documentation
Relational Persistence for Java
//$Id: SessionImpl.java 10689 2006-11-02 18:53:54Z [email protected] $
package org.hibernate.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Element;
import org.hibernate.CacheMode;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.Filter;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.ObjectDeletedException;
import org.hibernate.Query;
import org.hibernate.QueryException;
import org.hibernate.ReplicationMode;
import org.hibernate.SQLQuery;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionException;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.TransientObjectException;
import org.hibernate.UnresolvableObjectException;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.ActionQueue;
import org.hibernate.engine.CollectionEntry;
import org.hibernate.engine.EntityEntry;
import org.hibernate.engine.EntityKey;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.PersistenceContext;
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.StatefulPersistenceContext;
import org.hibernate.engine.Status;
import org.hibernate.engine.query.FilterQueryPlan;
import org.hibernate.engine.query.HQLQueryPlan;
import org.hibernate.engine.query.NativeSQLQueryPlan;
import org.hibernate.event.AutoFlushEvent;
import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.DeleteEvent;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.DirtyCheckEvent;
import org.hibernate.event.DirtyCheckEventListener;
import org.hibernate.event.EventListeners;
import org.hibernate.event.EventSource;
import org.hibernate.event.EvictEvent;
import org.hibernate.event.EvictEventListener;
import org.hibernate.event.FlushEvent;
import org.hibernate.event.FlushEventListener;
import org.hibernate.event.InitializeCollectionEvent;
import org.hibernate.event.InitializeCollectionEventListener;
import org.hibernate.event.LoadEvent;
import org.hibernate.event.LoadEventListener;
import org.hibernate.event.LockEvent;
import org.hibernate.event.LockEventListener;
import org.hibernate.event.MergeEvent;
import org.hibernate.event.MergeEventListener;
import org.hibernate.event.PersistEvent;
import org.hibernate.event.PersistEventListener;
import org.hibernate.event.RefreshEvent;
import org.hibernate.event.RefreshEventListener;
import org.hibernate.event.ReplicateEvent;
import org.hibernate.event.ReplicateEventListener;
import org.hibernate.event.SaveOrUpdateEvent;
import org.hibernate.event.SaveOrUpdateEventListener;
import org.hibernate.event.LoadEventListener.LoadType;
import org.hibernate.jdbc.Batcher;
import org.hibernate.jdbc.JDBCContext;
import org.hibernate.loader.criteria.CriteriaLoader;
import org.hibernate.loader.custom.CustomLoader;
import org.hibernate.loader.custom.CustomQuery;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.OuterJoinLoadable;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.stat.SessionStatistics;
import org.hibernate.stat.SessionStatisticsImpl;
import org.hibernate.tuple.DynamicMapInstantiator;
import org.hibernate.type.Type;
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.StringHelper;
/**
* Concrete implementation of a Session, and also the central, organizing component
* of Hibernate's internal implementation. As such, this class exposes two interfaces;
* Session itself, to the application, and SessionImplementor, to other components
* of Hibernate. This class is not threadsafe.
*
* @author Gavin King
*/
public final class SessionImpl extends AbstractSessionImpl
implements EventSource, org.hibernate.classic.Session, JDBCContext.Context {
// todo : need to find a clean way to handle the "event source" role
// a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
// passing around seperate reto interceptor, factory, actionQueue, and persistentContext is not manageable...
private static final Log log = LogFactory.getLog(SessionImpl.class);
private transient EntityMode entityMode = EntityMode.POJO;
private transient boolean autoClear; //for EJB3
private transient long timestamp;
private transient FlushMode flushMode = FlushMode.AUTO;
private transient CacheMode cacheMode = CacheMode.NORMAL;
private transient Interceptor interceptor;
private transient int dontFlushFromFind = 0;
private transient ActionQueue actionQueue;
private transient StatefulPersistenceContext persistenceContext;
private transient JDBCContext jdbcContext;
private transient EventListeners listeners;
private transient boolean flushBeforeCompletionEnabled;
private transient boolean autoCloseSessionEnabled;
private transient ConnectionReleaseMode connectionReleaseMode;
private transient String fetchProfile;
private transient Map enabledFilters = new HashMap();
private transient Session rootSession;
private transient Map childSessionsByEntityMode;
/**
* Constructor used in building "child sessions".
*
* @param parent The parent session
* @param entityMode
*/
private SessionImpl(SessionImpl parent, EntityMode entityMode) {
super( parent.factory );
this.rootSession = parent;
this.timestamp = parent.timestamp;
this.jdbcContext = parent.jdbcContext;
this.interceptor = parent.interceptor;
this.listeners = parent.listeners;
this.actionQueue = new ActionQueue( this );
this.entityMode = entityMode;
this.persistenceContext = new StatefulPersistenceContext( this );
this.flushBeforeCompletionEnabled = false;
this.autoCloseSessionEnabled = false;
this.connectionReleaseMode = null;
if ( factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor().openSession();
}
log.debug( "opened session [" + entityMode + "]" );
}
/**
* Constructor used for openSession(...) processing, as well as construction
* of sessions for getCurrentSession().
*
* @param connection The user-supplied connection to use for this session.
* @param factory The factory from which this session was obtained
* @param autoclose NOT USED
* @param timestamp The timestamp for this session
* @param interceptor The interceptor to be applied to this session
* @param entityMode The entity-mode for this session
* @param flushBeforeCompletionEnabled Should we auto flush before completion of transaction
* @param autoCloseSessionEnabled Should we auto close after completion of transaction
* @param connectionReleaseMode The mode by which we should release JDBC connections.
*/
SessionImpl(
final Connection connection,
final SessionFactoryImpl factory,
final boolean autoclose,
final long timestamp,
final Interceptor interceptor,
final EntityMode entityMode,
final boolean flushBeforeCompletionEnabled,
final boolean autoCloseSessionEnabled,
final ConnectionReleaseMode connectionReleaseMode) {
super( factory );
this.rootSession = null;
this.timestamp = timestamp;
this.entityMode = entityMode;
this.interceptor = interceptor;
this.listeners = factory.getEventListeners();
this.actionQueue = new ActionQueue( this );
this.persistenceContext = new StatefulPersistenceContext( this );
this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
this.autoCloseSessionEnabled = autoCloseSessionEnabled;
this.connectionReleaseMode = connectionReleaseMode;
this.jdbcContext = new JDBCContext( this, connection, interceptor );
if ( factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor().openSession();
}
if ( log.isDebugEnabled() ) {
log.debug( "opened session at timestamp: " + timestamp );
}
}
public Session getSession(EntityMode entityMode) {
if ( this.entityMode == entityMode ) {
return this;
}
if ( rootSession != null ) {
rootSession.getSession( entityMode );
}
errorIfClosed();
checkTransactionSynchStatus();
SessionImpl rtn = null;
if ( childSessionsByEntityMode == null ) {
childSessionsByEntityMode = new HashMap();
}
else {
rtn = (SessionImpl) childSessionsByEntityMode.get( entityMode );
}
if ( rtn == null ) {
rtn = new SessionImpl( this, entityMode );
childSessionsByEntityMode.put( entityMode, rtn );
}
return rtn;
}
public void clear() {
errorIfClosed();
checkTransactionSynchStatus();
persistenceContext.clear();
actionQueue.clear();
}
public Batcher getBatcher() {
errorIfClosed();
checkTransactionSynchStatus();
// TODO : should remove this exposure
// and have all references to the session's batcher use the ConnectionManager.
return jdbcContext.getConnectionManager().getBatcher();
}
public long getTimestamp() {
checkTransactionSynchStatus();
return timestamp;
}
public Connection close() throws HibernateException {
log.trace( "closing session" );
if ( isClosed() ) {
throw new SessionException( "Session was already closed" );
}
if ( factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor().closeSession();
}
try {
try {
if ( childSessionsByEntityMode != null ) {
Iterator childSessions = childSessionsByEntityMode.values().iterator();
while ( childSessions.hasNext() ) {
final SessionImpl child = ( SessionImpl ) childSessions.next();
child.close();
}
}
}
catch( Throwable t ) {
// just ignore
}
if ( rootSession == null ) {
return jdbcContext.getConnectionManager().close();
}
else {
return null;
}
}
finally {
setClosed();
cleanup();
}
}
public ConnectionReleaseMode getConnectionReleaseMode() {
checkTransactionSynchStatus();
return connectionReleaseMode;
}
public boolean isAutoCloseSessionEnabled() {
return autoCloseSessionEnabled;
}
public boolean isOpen() {
checkTransactionSynchStatus();
return !isClosed();
}
public boolean isFlushModeNever() {
return FlushMode.isManualFlushMode( getFlushMode() );
}
public boolean isFlushBeforeCompletionEnabled() {
return flushBeforeCompletionEnabled;
}
public void managedFlush() {
if ( isClosed() ) {
log.trace( "skipping auto-flush due to session closed" );
return;
}
log.trace("automatically flushing session");
flush();
if ( childSessionsByEntityMode != null ) {
Iterator iter = childSessionsByEntityMode.values().iterator();
while ( iter.hasNext() ) {
( (Session) iter.next() ).flush();
}
}
}
public boolean shouldAutoClose() {
return isAutoCloseSessionEnabled() && !isClosed();
}
public void managedClose() {
log.trace( "automatically closing session" );
close();
}
public Connection connection() throws HibernateException {
errorIfClosed();
return jdbcContext.borrowConnection();
}
public boolean isConnected() {
checkTransactionSynchStatus();
return !isClosed() && jdbcContext.getConnectionManager().isCurrentlyConnected();
}
public boolean isTransactionInProgress() {
checkTransactionSynchStatus();
return !isClosed() && jdbcContext.isTransactionInProgress();
}
public Connection disconnect() throws HibernateException {
errorIfClosed();
log.debug( "disconnecting session" );
return jdbcContext.getConnectionManager().manualDisconnect();
}
public void reconnect() throws HibernateException {
errorIfClosed();
log.debug( "reconnecting session" );
checkTransactionSynchStatus();
jdbcContext.getConnectionManager().manualReconnect();
}
public void reconnect(Connection conn) throws HibernateException {
errorIfClosed();
log.debug( "reconnecting session" );
checkTransactionSynchStatus();
jdbcContext.getConnectionManager().manualReconnect( conn );
}
public void beforeTransactionCompletion(Transaction tx) {
log.trace( "before transaction completion" );
if ( rootSession == null ) {
try {
interceptor.beforeTransactionCompletion(tx);
}
catch (Throwable t) {
log.error("exception in interceptor beforeTransactionCompletion()", t);
}
}
}
public void setAutoClear(boolean enabled) {
errorIfClosed();
autoClear = enabled;
}
/**
* Check if there is a Hibernate or JTA transaction in progress and,
* if there is not, flush if necessary, make sure the connection has
* been committed (if it is not in autocommit mode) and run the after
* completion processing
*/
public void afterOperation(boolean success) {
if ( !jdbcContext.isTransactionInProgress() ) {
jdbcContext.afterNontransactionalQuery( success );
}
}
public void afterTransactionCompletion(boolean success, Transaction tx) {
log.trace( "after transaction completion" );
persistenceContext.afterTransactionCompletion();
actionQueue.afterTransactionCompletion(success);
if ( rootSession == null && tx != null ) {
try {
interceptor.afterTransactionCompletion(tx);
}
catch (Throwable t) {
log.error("exception in interceptor afterTransactionCompletion()", t);
}
}
if ( autoClear ) {
clear();
}
}
/**
* clear all the internal collections, just
* to help the garbage collector, does not
* clear anything that is needed during the
* afterTransactionCompletion() phase
*/
private void cleanup() {
persistenceContext.clear();
}
public LockMode getCurrentLockMode(Object object) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
if ( object == null ) {
throw new NullPointerException( "null object passed to getCurrentLockMode()" );
}
if ( object instanceof HibernateProxy ) {
object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(this);
if ( object == null ) {
return LockMode.NONE;
}
}
EntityEntry e = persistenceContext.getEntry(object);
if ( e == null ) {
throw new TransientObjectException( "Given object not associated with the session" );
}
if ( e.getStatus() != Status.MANAGED ) {
throw new ObjectDeletedException(
"The given object was deleted",
e.getId(),
e.getPersister().getEntityName()
);
}
return e.getLockMode();
}
public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException {
errorIfClosed();
// todo : should this get moved to PersistentContext?
// logically, is PersistentContext the "thing" to which an interceptor gets attached?
final Object result = persistenceContext.getEntity(key);
if ( result == null ) {
final Object newObject = interceptor.getEntity( key.getEntityName(), key.getIdentifier() );
if ( newObject != null ) {
lock( newObject, LockMode.NONE );
}
return newObject;
}
else {
return result;
}
}
// saveOrUpdate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void saveOrUpdate(Object object) throws HibernateException {
saveOrUpdate(null, object);
}
public void saveOrUpdate(String entityName, Object obj) throws HibernateException {
fireSaveOrUpdate( new SaveOrUpdateEvent(entityName, obj, this) );
}
private void fireSaveOrUpdate(SaveOrUpdateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
SaveOrUpdateEventListener[] saveOrUpdateEventListener = listeners.getSaveOrUpdateEventListeners();
for ( int i = 0; i < saveOrUpdateEventListener.length; i++ ) {
saveOrUpdateEventListener[i].onSaveOrUpdate(event);
}
}
// save() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void save(Object obj, Serializable id) throws HibernateException {
save(null, obj, id);
}
public Serializable save(Object obj) throws HibernateException {
return save(null, obj);
}
public Serializable save(String entityName, Object object) throws HibernateException {
return fireSave( new SaveOrUpdateEvent(entityName, object, this) );
}
public void save(String entityName, Object object, Serializable id) throws HibernateException {
fireSave( new SaveOrUpdateEvent(entityName, object, id, this) );
}
private Serializable fireSave(SaveOrUpdateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
SaveOrUpdateEventListener[] saveEventListener = listeners.getSaveEventListeners();
for ( int i = 0; i < saveEventListener.length; i++ ) {
saveEventListener[i].onSaveOrUpdate(event);
}
return event.getResultId();
}
// update() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void update(Object obj) throws HibernateException {
update(null, obj);
}
public void update(Object obj, Serializable id) throws HibernateException {
update(null, obj, id);
}
public void update(String entityName, Object object) throws HibernateException {
fireUpdate( new SaveOrUpdateEvent(entityName, object, this) );
}
public void update(String entityName, Object object, Serializable id) throws HibernateException {
fireUpdate(new SaveOrUpdateEvent(entityName, object, id, this));
}
private void fireUpdate(SaveOrUpdateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
SaveOrUpdateEventListener[] updateEventListener = listeners.getUpdateEventListeners();
for ( int i = 0; i < updateEventListener.length; i++ ) {
updateEventListener[i].onSaveOrUpdate(event);
}
}
// lock() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void lock(String entityName, Object object, LockMode lockMode) throws HibernateException {
fireLock( new LockEvent(entityName, object, lockMode, this) );
}
public void lock(Object object, LockMode lockMode) throws HibernateException {
fireLock( new LockEvent(object, lockMode, this) );
}
private void fireLock(LockEvent lockEvent) {
errorIfClosed();
checkTransactionSynchStatus();
LockEventListener[] lockEventListener = listeners.getLockEventListeners();
for ( int i = 0; i < lockEventListener.length; i++ ) {
lockEventListener[i].onLock( lockEvent );
}
}
// persist() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void persist(String entityName, Object object) throws HibernateException {
firePersist( new PersistEvent(entityName, object, this) );
}
public void persist(Object object) throws HibernateException {
persist(null, object);
}
public void persist(String entityName, Object object, Map copiedAlready)
throws HibernateException {
firePersist( copiedAlready, new PersistEvent(entityName, object, this) );
}
private void firePersist(Map copiedAlready, PersistEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
PersistEventListener[] persistEventListener = listeners.getPersistEventListeners();
for ( int i = 0; i < persistEventListener.length; i++ ) {
persistEventListener[i].onPersist(event, copiedAlready);
}
}
private void firePersist(PersistEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
PersistEventListener[] createEventListener = listeners.getPersistEventListeners();
for ( int i = 0; i < createEventListener.length; i++ ) {
createEventListener[i].onPersist(event);
}
}
// persistOnFlush() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void persistOnFlush(String entityName, Object object)
throws HibernateException {
firePersistOnFlush( new PersistEvent(entityName, object, this) );
}
public void persistOnFlush(Object object) throws HibernateException {
persist(null, object);
}
public void persistOnFlush(String entityName, Object object, Map copiedAlready)
throws HibernateException {
firePersistOnFlush( copiedAlready, new PersistEvent(entityName, object, this) );
}
private void firePersistOnFlush(Map copiedAlready, PersistEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
PersistEventListener[] persistEventListener = listeners.getPersistOnFlushEventListeners();
for ( int i = 0; i < persistEventListener.length; i++ ) {
persistEventListener[i].onPersist(event, copiedAlready);
}
}
private void firePersistOnFlush(PersistEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
PersistEventListener[] createEventListener = listeners.getPersistOnFlushEventListeners();
for ( int i = 0; i < createEventListener.length; i++ ) {
createEventListener[i].onPersist(event);
}
}
// merge() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public Object merge(String entityName, Object object) throws HibernateException {
return fireMerge( new MergeEvent(entityName, object, this) );
}
public Object merge(Object object) throws HibernateException {
return merge(null, object);
}
public void merge(String entityName, Object object, Map copiedAlready) throws HibernateException {
fireMerge( copiedAlready, new MergeEvent(entityName, object, this) );
}
private Object fireMerge(MergeEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
for ( int i = 0; i < mergeEventListener.length; i++ ) {
mergeEventListener[i].onMerge(event);
}
return event.getResult();
}
private void fireMerge(Map copiedAlready, MergeEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
for ( int i = 0; i < mergeEventListener.length; i++ ) {
mergeEventListener[i].onMerge(event, copiedAlready);
}
}
// saveOrUpdateCopy() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public Object saveOrUpdateCopy(String entityName, Object object)
throws HibernateException {
return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, this) );
}
public Object saveOrUpdateCopy(Object object) throws HibernateException {
return saveOrUpdateCopy( null, object );
}
public Object saveOrUpdateCopy(String entityName, Object object, Serializable id)
throws HibernateException {
return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, id, this) );
}
public Object saveOrUpdateCopy(Object object, Serializable id)
throws HibernateException {
return saveOrUpdateCopy( null, object, id );
}
public void saveOrUpdateCopy(String entityName, Object object, Map copiedAlready)
throws HibernateException {
fireSaveOrUpdateCopy( copiedAlready, new MergeEvent( entityName, object, this ) );
}
private void fireSaveOrUpdateCopy(Map copiedAlready, MergeEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
MergeEventListener[] saveOrUpdateCopyEventListener = listeners.getSaveOrUpdateCopyEventListeners();
for ( int i = 0; i < saveOrUpdateCopyEventListener.length; i++ ) {
saveOrUpdateCopyEventListener[i].onMerge(event, copiedAlready);
}
}
private Object fireSaveOrUpdateCopy(MergeEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
MergeEventListener[] saveOrUpdateCopyEventListener = listeners.getSaveOrUpdateCopyEventListeners();
for ( int i = 0; i < saveOrUpdateCopyEventListener.length; i++ ) {
saveOrUpdateCopyEventListener[i].onMerge(event);
}
return event.getResult();
}
// delete() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Delete a persistent object
*/
public void delete(Object object) throws HibernateException {
fireDelete( new DeleteEvent(object, this) );
}
/**
* Delete a persistent object (by explicit entity name)
*/
public void delete(String entityName, Object object) throws HibernateException {
fireDelete( new DeleteEvent( entityName, object, this ) );
}
/**
* Delete a persistent object
*/
public void delete(String entityName, Object object, boolean isCascadeDeleteEnabled, Set transientEntities) throws HibernateException {
fireDelete( new DeleteEvent( entityName, object, isCascadeDeleteEnabled, this ), transientEntities );
}
private void fireDelete(DeleteEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
for ( int i = 0; i < deleteEventListener.length; i++ ) {
deleteEventListener[i].onDelete( event );
}
}
private void fireDelete(DeleteEvent event, Set transientEntities) {
errorIfClosed();
checkTransactionSynchStatus();
DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
for ( int i = 0; i < deleteEventListener.length; i++ ) {
deleteEventListener[i].onDelete( event, transientEntities );
}
}
// load()/get() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void load(Object object, Serializable id) throws HibernateException {
LoadEvent event = new LoadEvent(id, object, this);
fireLoad( event, LoadEventListener.RELOAD );
}
public Object load(Class entityClass, Serializable id) throws HibernateException {
return load( entityClass.getName(), id );
}
public Object load(String entityName, Serializable id) throws HibernateException {
LoadEvent event = new LoadEvent(id, entityName, false, this);
boolean success = false;
try {
fireLoad( event, LoadEventListener.LOAD );
if ( event.getResult() == null ) {
getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
}
success = true;
return event.getResult();
}
finally {
afterOperation(success);
}
}
public Object get(Class entityClass, Serializable id) throws HibernateException {
return get( entityClass.getName(), id );
}
public Object get(String entityName, Serializable id) throws HibernateException {
LoadEvent event = new LoadEvent(id, entityName, false, this);
boolean success = false;
try {
fireLoad(event, LoadEventListener.GET);
success = true;
return event.getResult();
}
finally {
afterOperation(success);
}
}
/**
* Load the data for the object with the specified id into a newly created object.
* This is only called when lazily initializing a proxy.
* Do NOT return a proxy.
*/
public Object immediateLoad(String entityName, Serializable id) throws HibernateException {
if ( log.isDebugEnabled() ) {
EntityPersister persister = getFactory().getEntityPersister(entityName);
log.debug( "initializing proxy: " + MessageHelper.infoString( persister, id, getFactory() ) );
}
LoadEvent event = new LoadEvent(id, entityName, true, this);
fireLoad(event, LoadEventListener.IMMEDIATE_LOAD);
return event.getResult();
}
public Object internalLoad(String entityName, Serializable id, boolean eager, boolean nullable) throws HibernateException {
// todo : remove
LoadEventListener.LoadType type = nullable ?
LoadEventListener.INTERNAL_LOAD_NULLABLE :
eager ? LoadEventListener.INTERNAL_LOAD_EAGER : LoadEventListener.INTERNAL_LOAD_LAZY;
LoadEvent event = new LoadEvent(id, entityName, true, this);
fireLoad(event, type);
if ( !nullable ) {
UnresolvableObjectException.throwIfNull( event.getResult(), id, entityName );
}
return event.getResult();
}
public Object load(Class entityClass, Serializable id, LockMode lockMode) throws HibernateException {
return load( entityClass.getName(), id, lockMode );
}
public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
fireLoad( event, LoadEventListener.LOAD );
return event.getResult();
}
public Object get(Class entityClass, Serializable id, LockMode lockMode) throws HibernateException {
return get( entityClass.getName(), id, lockMode );
}
public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
fireLoad(event, LoadEventListener.GET);
return event.getResult();
}
private void fireLoad(LoadEvent event, LoadType loadType) {
errorIfClosed();
checkTransactionSynchStatus();
LoadEventListener[] loadEventListener = listeners.getLoadEventListeners();
for ( int i = 0; i < loadEventListener.length; i++ ) {
loadEventListener[i].onLoad(event, loadType);
}
}
// refresh() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void refresh(Object object) throws HibernateException {
fireRefresh( new RefreshEvent(object, this) );
}
public void refresh(Object object, LockMode lockMode) throws HibernateException {
fireRefresh( new RefreshEvent(object, lockMode, this) );
}
public void refresh(Object object, Map refreshedAlready) throws HibernateException {
fireRefresh( refreshedAlready, new RefreshEvent(object, this) );
}
private void fireRefresh(RefreshEvent refreshEvent) {
errorIfClosed();
checkTransactionSynchStatus();
RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
for ( int i = 0; i < refreshEventListener.length; i++ ) {
refreshEventListener[i].onRefresh( refreshEvent );
}
}
private void fireRefresh(Map refreshedAlready, RefreshEvent refreshEvent) {
errorIfClosed();
checkTransactionSynchStatus();
RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
for ( int i = 0; i < refreshEventListener.length; i++ ) {
refreshEventListener[i].onRefresh( refreshEvent, refreshedAlready );
}
}
// replicate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void replicate(Object obj, ReplicationMode replicationMode) throws HibernateException {
fireReplicate( new ReplicateEvent(obj, replicationMode, this) );
}
public void replicate(String entityName, Object obj, ReplicationMode replicationMode)
throws HibernateException {
fireReplicate( new ReplicateEvent(entityName, obj, replicationMode, this) );
}
private void fireReplicate(ReplicateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
ReplicateEventListener[] replicateEventListener = listeners.getReplicateEventListeners();
for ( int i = 0; i < replicateEventListener.length; i++ ) {
replicateEventListener[i].onReplicate(event);
}
}
// evict() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* remove any hard references to the entity that are held by the infrastructure
* (references held by application or other persistant instances are okay)
*/
public void evict(Object object) throws HibernateException {
fireEvict( new EvictEvent(object, this) );
}
private void fireEvict(EvictEvent evictEvent) {
errorIfClosed();
checkTransactionSynchStatus();
EvictEventListener[] evictEventListener = listeners.getEvictEventListeners();
for ( int i = 0; i < evictEventListener.length; i++ ) {
evictEventListener[i].onEvict( evictEvent );
}
}
/**
* detect in-memory changes, determine if the changes are to tables
* named in the query and, if so, complete execution the flush
*/
protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
errorIfClosed();
if ( ! isTransactionInProgress() ) {
// do not auto-flush while outside a transaction
return false;
}
AutoFlushEvent event = new AutoFlushEvent(querySpaces, this);
AutoFlushEventListener[] autoFlushEventListener = listeners.getAutoFlushEventListeners();
for ( int i = 0; i < autoFlushEventListener.length; i++ ) {
autoFlushEventListener[i].onAutoFlush(event);
}
return event.isFlushRequired();
}
public boolean isDirty() throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
log.debug("checking session dirtiness");
if ( actionQueue.areInsertionsOrDeletionsQueued() ) {
log.debug("session dirty (scheduled updates and insertions)");
return true;
}
else {
DirtyCheckEvent event = new DirtyCheckEvent(this);
DirtyCheckEventListener[] dirtyCheckEventListener = listeners.getDirtyCheckEventListeners();
for ( int i = 0; i < dirtyCheckEventListener.length; i++ ) {
dirtyCheckEventListener[i].onDirtyCheck(event);
}
return event.isDirty();
}
}
public void flush() throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
if ( persistenceContext.getCascadeLevel() > 0 ) {
throw new HibernateException("Flush during cascade is dangerous");
}
FlushEventListener[] flushEventListener = listeners.getFlushEventListeners();
for ( int i = 0; i < flushEventListener.length; i++ ) {
flushEventListener[i].onFlush( new FlushEvent(this) );
}
}
public void forceFlush(EntityEntry entityEntry) throws HibernateException {
errorIfClosed();
if ( log.isDebugEnabled() ) {
log.debug(
"flushing to force deletion of re-saved object: " +
MessageHelper.infoString( entityEntry.getPersister(), entityEntry.getId(), getFactory() )
);
}
if ( persistenceContext.getCascadeLevel() > 0 ) {
throw new ObjectDeletedException(
"deleted object would be re-saved by cascade (remove deleted object from associations)",
entityEntry.getId(),
entityEntry.getPersister().getEntityName()
);
}
flush();
}
public Filter getEnabledFilter(String filterName) {
checkTransactionSynchStatus();
return (Filter) enabledFilters.get(filterName);
}
public Filter enableFilter(String filterName) {
errorIfClosed();
checkTransactionSynchStatus();
FilterImpl filter = new FilterImpl( factory.getFilterDefinition(filterName) );
enabledFilters.put(filterName, filter);
return filter;
}
public void disableFilter(String filterName) {
errorIfClosed();
checkTransactionSynchStatus();
enabledFilters.remove(filterName);
}
public Object getFilterParameterValue(String filterParameterName) {
errorIfClosed();
checkTransactionSynchStatus();
String[] parsed = parseFilterParameterName(filterParameterName);
FilterImpl filter = (FilterImpl) enabledFilters.get( parsed[0] );
if (filter == null) {
throw new IllegalArgumentException("Filter [" + parsed[0] + "] currently not enabled");
}
return filter.getParameter( parsed[1] );
}
public Type getFilterParameterType(String filterParameterName) {
errorIfClosed();
checkTransactionSynchStatus();
String[] parsed = parseFilterParameterName(filterParameterName);
FilterDefinition filterDef = factory.getFilterDefinition( parsed[0] );
if (filterDef == null) {
throw new IllegalArgumentException("Filter [" + parsed[0] + "] not defined");
}
Type type = filterDef.getParameterType( parsed[1] );
if (type == null) {
// this is an internal error of some sort...
throw new InternalError("Unable to locate type for filter parameter");
}
return type;
}
public Map getEnabledFilters() {
errorIfClosed();
checkTransactionSynchStatus();
// First, validate all the enabled filters...
//TODO: this implementation has bad performance
Iterator itr = enabledFilters.values().iterator();
while ( itr.hasNext() ) {
final Filter filter = (Filter) itr.next();
filter.validate();
}
return enabledFilters;
}
private String[] parseFilterParameterName(String filterParameterName) {
int dot = filterParameterName.indexOf('.');
if (dot <= 0) {
throw new IllegalArgumentException("Invalid filter-parameter name format"); // TODO: what type?
}
String filterName = filterParameterName.substring(0, dot);
String parameterName = filterParameterName.substring(dot+1);
return new String[] {filterName, parameterName};
}
/**
* Retrieve a list of persistent objects using a hibernate query
*/
public List find(String query) throws HibernateException {
return list( query, new QueryParameters() );
}
public List find(String query, Object value, Type type) throws HibernateException {
return list( query, new QueryParameters(type, value) );
}
public List find(String query, Object[] values, Type[] types) throws HibernateException {
return list( query, new QueryParameters(types, values) );
}
public List list(String query, QueryParameters queryParameters) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
queryParameters.validateParameters();
HQLQueryPlan plan = getHQLQueryPlan( query, false );
autoFlushIfRequired( plan.getQuerySpaces() );
List results = CollectionHelper.EMPTY_LIST;
boolean success = false;
dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
try {
results = plan.performList( queryParameters, this );
success = true;
}
finally {
dontFlushFromFind--;
afterOperation(success);
}
return results;
}
public int executeUpdate(String query, QueryParameters queryParameters) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
queryParameters.validateParameters();
HQLQueryPlan plan = getHQLQueryPlan( query, false );
autoFlushIfRequired( plan.getQuerySpaces() );
boolean success = false;
int result = 0;
try {
result = plan.performExecuteUpdate( queryParameters, this );
success = true;
}
finally {
afterOperation(success);
}
return result;
}
public int executeNativeUpdate(NativeSQLQuerySpecification nativeQuerySpecification,
QueryParameters queryParameters) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
queryParameters.validateParameters();
NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeQuerySpecification);
autoFlushIfRequired( plan.getCustomQuery().getQuerySpaces() );
boolean success = false;
int result = 0;
try {
result = plan.performExecuteUpdate(queryParameters, this);
success = true;
} finally {
afterOperation(success);
}
return result;
}
public Iterator iterate(String query) throws HibernateException {
return iterate( query, new QueryParameters() );
}
public Iterator iterate(String query, Object value, Type type) throws HibernateException {
return iterate( query, new QueryParameters(type, value) );
}
public Iterator iterate(String query, Object[] values, Type[] types) throws HibernateException {
return iterate( query, new QueryParameters(types, values) );
}
public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
queryParameters.validateParameters();
HQLQueryPlan plan = getHQLQueryPlan( query, true );
autoFlushIfRequired( plan.getQuerySpaces() );
dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
try {
return plan.performIterate( queryParameters, this );
}
finally {
dontFlushFromFind--;
}
}
public ScrollableResults scroll(String query, QueryParameters queryParameters) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
HQLQueryPlan plan = getHQLQueryPlan( query, false );
autoFlushIfRequired( plan.getQuerySpaces() );
dontFlushFromFind++;
try {
return plan.performScroll( queryParameters, this );
}
finally {
dontFlushFromFind--;
}
}
public int delete(String query) throws HibernateException {
return delete( query, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY );
}
public int delete(String query, Object value, Type type) throws HibernateException {
return delete( query, new Object[]{value}, new Type[]{type} );
}
public int delete(String query, Object[] values, Type[] types) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
if ( query == null ) {
throw new IllegalArgumentException("attempt to perform delete-by-query with null query");
}
if ( log.isTraceEnabled() ) {
log.trace( "delete: " + query );
if ( values.length != 0 ) {
log.trace( "parameters: " + StringHelper.toString( values ) );
}
}
List list = find( query, values, types );
int deletionCount = list.size();
for ( int i = 0; i < deletionCount; i++ ) {
delete( list.get( i ) );
}
return deletionCount;
}
public Query createFilter(Object collection, String queryString) {
errorIfClosed();
checkTransactionSynchStatus();
CollectionFilterImpl filter = new CollectionFilterImpl(
queryString,
collection,
this,
getFilterQueryPlan( collection, queryString, null, false ).getParameterMetadata()
);
filter.setComment( queryString );
return filter;
}
public Query getNamedQuery(String queryName) throws MappingException {
errorIfClosed();
checkTransactionSynchStatus();
return super.getNamedQuery(queryName);
}
public Object instantiate(String entityName, Serializable id) throws HibernateException {
return instantiate( factory.getEntityPersister(entityName), id );
}
/**
* give the interceptor an opportunity to override the default instantiation
*/
public Object instantiate(EntityPersister persister, Serializable id) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
Object result = interceptor.instantiate( persister.getEntityName(), entityMode, id );
if ( result == null ) {
result = persister.instantiate( id, entityMode );
}
return result;
}
public EntityMode getEntityMode() {
checkTransactionSynchStatus();
return entityMode;
}
public void setFlushMode(FlushMode flushMode) {
errorIfClosed();
checkTransactionSynchStatus();
if ( log.isTraceEnabled() ) {
log.trace("setting flush mode to: " + flushMode);
}
this.flushMode = flushMode;
}
public FlushMode getFlushMode() {
checkTransactionSynchStatus();
return flushMode;
}
public CacheMode getCacheMode() {
checkTransactionSynchStatus();
return cacheMode;
}
public void setCacheMode(CacheMode cacheMode) {
errorIfClosed();
checkTransactionSynchStatus();
if ( log.isTraceEnabled() ) {
log.trace("setting cache mode to: " + cacheMode);
}
this.cacheMode= cacheMode;
}
public Transaction getTransaction() throws HibernateException {
errorIfClosed();
return jdbcContext.getTransaction();
}
public Transaction beginTransaction() throws HibernateException {
errorIfClosed();
if ( rootSession != null ) {
// todo : should seriously consider not allowing a txn to begin from a child session
// can always route the request to the root session...
log.warn( "Transaction started on non-root session" );
}
Transaction result = getTransaction();
result.begin();
return result;
}
public void afterTransactionBegin(Transaction tx) {
errorIfClosed();
interceptor.afterTransactionBegin(tx);
}
public EntityPersister getEntityPersister(final String entityName, final Object object) {
errorIfClosed();
if (entityName==null) {
return factory.getEntityPersister( guessEntityName( object ) );
}
else {
// try block is a hack around fact that currently tuplizers are not
// given the opportunity to resolve a subclass entity name. this
// allows the (we assume custom) interceptor the ability to
// influence this decision if we were not able to based on the
// given entityName
try {
return factory.getEntityPersister( entityName )
.getSubclassEntityPersister( object, getFactory(), entityMode );
}
catch( HibernateException e ) {
try {
return getEntityPersister( null, object );
}
catch( HibernateException e2 ) {
throw e;
}
}
}
}
// not for internal use:
public Serializable getIdentifier(Object object) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
if ( object instanceof HibernateProxy ) {
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
if ( li.getSession() != this ) {
throw new TransientObjectException( "The proxy was not associated with this session" );
}
return li.getIdentifier();
}
else {
EntityEntry entry = persistenceContext.getEntry(object);
if ( entry == null ) {
throw new TransientObjectException( "The instance was not associated with this session" );
}
return entry.getId();
}
}
/**
* Get the id value for an object that is actually associated with the session. This
* is a bit stricter than getEntityIdentifierIfNotUnsaved().
*/
public Serializable getContextEntityIdentifier(Object object) {
errorIfClosed();
if ( object instanceof HibernateProxy ) {
return getProxyIdentifier(object);
}
else {
EntityEntry entry = persistenceContext.getEntry(object);
return entry != null ? entry.getId() : null;
}
}
private Serializable getProxyIdentifier(Object proxy) {
return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getIdentifier();
}
public Collection filter(Object collection, String filter) throws HibernateException {
return listFilter( collection, filter, new QueryParameters( new Type[1], new Object[1] ) );
}
public Collection filter(Object collection, String filter, Object value, Type type) throws HibernateException {
return listFilter( collection, filter, new QueryParameters( new Type[]{null, type}, new Object[]{null, value} ) );
}
public Collection filter(Object collection, String filter, Object[] values, Type[] types)
throws HibernateException {
Object[] vals = new Object[values.length + 1];
Type[] typs = new Type[types.length + 1];
System.arraycopy( values, 0, vals, 1, values.length );
System.arraycopy( types, 0, typs, 1, types.length );
return listFilter( collection, filter, new QueryParameters( typs, vals ) );
}
private FilterQueryPlan getFilterQueryPlan(
Object collection,
String filter,
QueryParameters parameters,
boolean shallow) throws HibernateException {
if ( collection == null ) {
throw new NullPointerException( "null collection passed to filter" );
}
CollectionEntry entry = persistenceContext.getCollectionEntryOrNull( collection );
final CollectionPersister roleBeforeFlush = (entry == null) ? null : entry.getLoadedPersister();
FilterQueryPlan plan = null;
if ( roleBeforeFlush == null ) {
// if it was previously unreferenced, we need to flush in order to
// get its state into the database in order to execute query
flush();
entry = persistenceContext.getCollectionEntryOrNull( collection );
CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
if ( roleAfterFlush == null ) {
throw new QueryException( "The collection was unreferenced" );
}
plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleAfterFlush.getRole(), shallow, getEnabledFilters() );
}
else {
// otherwise, we only need to flush if there are in-memory changes
// to the queried tables
plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleBeforeFlush.getRole(), shallow, getEnabledFilters() );
if ( autoFlushIfRequired( plan.getQuerySpaces() ) ) {
// might need to run a different filter entirely after the flush
// because the collection role may have changed
entry = persistenceContext.getCollectionEntryOrNull( collection );
CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
if ( roleBeforeFlush != roleAfterFlush ) {
if ( roleAfterFlush == null ) {
throw new QueryException( "The collection was dereferenced" );
}
plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleAfterFlush.getRole(), shallow, getEnabledFilters() );
}
}
}
if ( parameters != null ) {
parameters.getPositionalParameterValues()[0] = entry.getLoadedKey();
parameters.getPositionalParameterTypes()[0] = entry.getLoadedPersister().getKeyType();
}
return plan;
}
public List listFilter(Object collection, String filter, QueryParameters queryParameters)
throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, false );
List results = CollectionHelper.EMPTY_LIST;
boolean success = false;
dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
try {
results = plan.performList( queryParameters, this );
success = true;
}
finally {
dontFlushFromFind--;
afterOperation(success);
}
return results;
}
public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters)
throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, true );
return plan.performIterate( queryParameters, this );
}
public Criteria createCriteria(Class persistentClass, String alias) {
errorIfClosed();
checkTransactionSynchStatus();
return new CriteriaImpl( persistentClass.getName(), alias, this );
}
public Criteria createCriteria(String entityName, String alias) {
errorIfClosed();
checkTransactionSynchStatus();
return new CriteriaImpl(entityName, alias, this);
}
public Criteria createCriteria(Class persistentClass) {
errorIfClosed();
checkTransactionSynchStatus();
return new CriteriaImpl( persistentClass.getName(), this );
}
public Criteria createCriteria(String entityName) {
errorIfClosed();
checkTransactionSynchStatus();
return new CriteriaImpl(entityName, this);
}
public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
errorIfClosed();
checkTransactionSynchStatus();
String entityName = criteria.getEntityOrClassName();
CriteriaLoader loader = new CriteriaLoader(
getOuterJoinLoadable(entityName),
factory,
criteria,
entityName,
getEnabledFilters()
);
autoFlushIfRequired( loader.getQuerySpaces() );
dontFlushFromFind++;
try {
return loader.scroll(this, scrollMode);
}
finally {
dontFlushFromFind--;
}
}
public List list(CriteriaImpl criteria) throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
String[] implementors = factory.getImplementors( criteria.getEntityOrClassName() );
int size = implementors.length;
CriteriaLoader[] loaders = new CriteriaLoader[size];
Set spaces = new HashSet();
for( int i=0; i entityName, but that would mean nodeName being distinct
entity = ( (Element) object ).getName();
}
else {
entity = object.getClass().getName();
}
}
return entity;
}
public void cancelQuery() throws HibernateException {
errorIfClosed();
getBatcher().cancelLastQuery();
}
public Interceptor getInterceptor() {
checkTransactionSynchStatus();
return interceptor;
}
public int getDontFlushFromFind() {
return dontFlushFromFind;
}
public String toString() {
StringBuffer buf = new StringBuffer(500)
.append( "SessionImpl(" );
if ( !isClosed() ) {
buf.append(persistenceContext)
.append(";")
.append(actionQueue);
}
else {
buf.append("");
}
return buf.append(')').toString();
}
public EventListeners getListeners() {
return listeners;
}
public ActionQueue getActionQueue() {
errorIfClosed();
checkTransactionSynchStatus();
return actionQueue;
}
public PersistenceContext getPersistenceContext() {
errorIfClosed();
checkTransactionSynchStatus();
return persistenceContext;
}
public SessionStatistics getStatistics() {
checkTransactionSynchStatus();
return new SessionStatisticsImpl(this);
}
public boolean isEventSource() {
checkTransactionSynchStatus();
return true;
}
public void setReadOnly(Object entity, boolean readOnly) {
errorIfClosed();
checkTransactionSynchStatus();
persistenceContext.setReadOnly(entity, readOnly);
}
public void afterScrollOperation() {
// nothing to do in a stateful session
}
public String getFetchProfile() {
checkTransactionSynchStatus();
return fetchProfile;
}
public JDBCContext getJDBCContext() {
errorIfClosed();
checkTransactionSynchStatus();
return jdbcContext;
}
public void setFetchProfile(String fetchProfile) {
errorIfClosed();
checkTransactionSynchStatus();
this.fetchProfile = fetchProfile;
}
private void checkTransactionSynchStatus() {
if ( jdbcContext != null && !isClosed() ) {
jdbcContext.registerSynchronizationIfPossible();
}
}
/**
* Used by JDK serialization...
*
* @param ois The input stream from which we are being read...
* @throws IOException Indicates a general IO stream exception
* @throws ClassNotFoundException Indicates a class resolution issue
*/
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
log.trace( "deserializing session" );
boolean isRootSession = ois.readBoolean();
connectionReleaseMode = ConnectionReleaseMode.parse( ( String ) ois.readObject() );
entityMode = EntityMode.parse( ( String ) ois.readObject() );
autoClear = ois.readBoolean();
flushMode = FlushMode.parse( ( String ) ois.readObject() );
cacheMode = CacheMode.parse( ( String ) ois.readObject() );
flushBeforeCompletionEnabled = ois.readBoolean();
autoCloseSessionEnabled = ois.readBoolean();
fetchProfile = ( String ) ois.readObject();
interceptor = ( Interceptor ) ois.readObject();
factory = SessionFactoryImpl.deserialize( ois );
listeners = factory.getEventListeners();
if ( isRootSession ) {
jdbcContext = JDBCContext.deserialize( ois, this, interceptor );
}
persistenceContext = StatefulPersistenceContext.deserialize( ois, this );
actionQueue = ActionQueue.deserialize( ois, this );
enabledFilters = ( Map ) ois.readObject();
childSessionsByEntityMode = ( Map ) ois.readObject();
Iterator iter = enabledFilters.values().iterator();
while ( iter.hasNext() ) {
( ( FilterImpl ) iter.next() ).afterDeserialize(factory);
}
if ( isRootSession && childSessionsByEntityMode != null ) {
iter = childSessionsByEntityMode.values().iterator();
while ( iter.hasNext() ) {
final SessionImpl child = ( ( SessionImpl ) iter.next() );
child.rootSession = this;
child.jdbcContext = this.jdbcContext;
}
}
}
/**
* Used by JDK serialization...
*
* @param oos The output stream to which we are being written...
* @throws IOException Indicates a general IO stream exception
*/
private void writeObject(ObjectOutputStream oos) throws IOException {
if ( !jdbcContext.getConnectionManager().isReadyForSerialization() ) {
throw new IllegalStateException( "Cannot serialize a session while connected" );
}
log.trace( "serializing session" );
oos.writeBoolean( rootSession == null );
oos.writeObject( connectionReleaseMode.toString() );
oos.writeObject( entityMode.toString() );
oos.writeBoolean( autoClear );
oos.writeObject( flushMode.toString() );
oos.writeObject( cacheMode.toString() );
oos.writeBoolean( flushBeforeCompletionEnabled );
oos.writeBoolean( autoCloseSessionEnabled );
oos.writeObject( fetchProfile );
// we need to writeObject() on this since interceptor is user defined
oos.writeObject( interceptor );
factory.serialize( oos );
if ( rootSession == null ) {
jdbcContext.serialize( oos );
}
persistenceContext.serialize( oos );
actionQueue.serialize( oos );
// todo : look at optimizing these...
oos.writeObject( enabledFilters );
oos.writeObject( childSessionsByEntityMode );
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy