Save This Page
Home » Hibernate-3.3.2.GA » org.hibernate » engine » [javadoc | source]
    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.engine;
   26   
   27   import java.io.Serializable;
   28   import java.io.ObjectOutputStream;
   29   import java.io.IOException;
   30   import java.io.ObjectInputStream;
   31   
   32   
   33   import org.hibernate.EntityMode;
   34   import org.hibernate.HibernateException;
   35   import org.hibernate.LockMode;
   36   import org.hibernate.intercept.FieldInterceptionHelper;
   37   import org.hibernate.persister.entity.EntityPersister;
   38   import org.hibernate.persister.entity.UniqueKeyLoadable;
   39   import org.hibernate.pretty.MessageHelper;
   40   
   41   /**
   42    * We need an entry to tell us all about the current state
   43    * of an object with respect to its persistent state
   44    * 
   45    * @author Gavin King
   46    */
   47   public final class EntityEntry implements Serializable {
   48   
   49   	private LockMode lockMode;
   50   	private Status status;
   51   	private final Serializable id;
   52   	private Object[] loadedState;
   53   	private Object[] deletedState;
   54   	private boolean existsInDatabase;
   55   	private Object version;
   56   	private transient EntityPersister persister; // for convenience to save some lookups
   57   	private final EntityMode entityMode;
   58   	private final String entityName;
   59   	private boolean isBeingReplicated;
   60   	private boolean loadedWithLazyPropertiesUnfetched; //NOTE: this is not updated when properties are fetched lazily!
   61   	private final transient Object rowId;
   62   
   63   	EntityEntry(
   64   			final Status status,
   65   			final Object[] loadedState,
   66   			final Object rowId,
   67   			final Serializable id,
   68   			final Object version,
   69   			final LockMode lockMode,
   70   			final boolean existsInDatabase,
   71   			final EntityPersister persister,
   72   			final EntityMode entityMode,
   73   			final boolean disableVersionIncrement,
   74   			final boolean lazyPropertiesAreUnfetched) {
   75   		this.status=status;
   76   		this.loadedState=loadedState;
   77   		this.id=id;
   78   		this.rowId=rowId;
   79   		this.existsInDatabase=existsInDatabase;
   80   		this.version=version;
   81   		this.lockMode=lockMode;
   82   		this.isBeingReplicated=disableVersionIncrement;
   83   		this.loadedWithLazyPropertiesUnfetched = lazyPropertiesAreUnfetched;
   84   		this.persister=persister;
   85   		this.entityMode = entityMode;
   86   		this.entityName = persister == null ?
   87   				null : persister.getEntityName();
   88   	}
   89   
   90   	/**
   91   	 * Used during custom deserialization
   92   	 */
   93   	private EntityEntry(
   94   			final SessionFactoryImplementor factory,
   95   			final String entityName,
   96   			final Serializable id,
   97   			final EntityMode entityMode,
   98   			final Status status,
   99   			final Object[] loadedState,
  100   	        final Object[] deletedState,
  101   			final Object version,
  102   			final LockMode lockMode,
  103   			final boolean existsInDatabase,
  104   			final boolean isBeingReplicated,
  105   			final boolean loadedWithLazyPropertiesUnfetched) {
  106   		this.entityName = entityName;
  107   		this.persister = factory.getEntityPersister( entityName );
  108   		this.id = id;
  109   		this.entityMode = entityMode;
  110   		this.status = status;
  111   		this.loadedState = loadedState;
  112   		this.deletedState = deletedState;
  113   		this.version = version;
  114   		this.lockMode = lockMode;
  115   		this.existsInDatabase = existsInDatabase;
  116   		this.isBeingReplicated = isBeingReplicated;
  117   		this.loadedWithLazyPropertiesUnfetched = loadedWithLazyPropertiesUnfetched;
  118   		this.rowId = null; // this is equivalent to the old behavior...
  119   	}
  120   
  121   	public LockMode getLockMode() {
  122   		return lockMode;
  123   	}
  124   
  125   	public void setLockMode(LockMode lockMode) {
  126   		this.lockMode = lockMode;
  127   	}
  128   
  129   	public Status getStatus() {
  130   		return status;
  131   	}
  132   
  133   	public void setStatus(Status status) {
  134   		if (status==Status.READ_ONLY) {
  135   			loadedState = null; //memory optimization
  136   		}
  137   		this.status = status;
  138   	}
  139   
  140   	public Serializable getId() {
  141   		return id;
  142   	}
  143   
  144   	public Object[] getLoadedState() {
  145   		return loadedState;
  146   	}
  147   
  148   	public Object[] getDeletedState() {
  149   		return deletedState;
  150   	}
  151   
  152   	public void setDeletedState(Object[] deletedState) {
  153   		this.deletedState = deletedState;
  154   	}
  155   
  156   	public boolean isExistsInDatabase() {
  157   		return existsInDatabase;
  158   	}
  159   
  160   	public Object getVersion() {
  161   		return version;
  162   	}
  163   
  164   	public EntityPersister getPersister() {
  165   		return persister;
  166   	}
  167   
  168   	void afterDeserialize(SessionFactoryImplementor factory) {
  169   		persister = factory.getEntityPersister( entityName );
  170   	}
  171   
  172   	public String getEntityName() {
  173   		return entityName;
  174   	}
  175   
  176   	public boolean isBeingReplicated() {
  177   		return isBeingReplicated;
  178   	}
  179   	
  180   	public Object getRowId() {
  181   		return rowId;
  182   	}
  183   	
  184   	/**
  185   	 * After actually updating the database, update the snapshot information,
  186   	 * and escalate the lock mode
  187   	 */
  188   	public void postUpdate(Object entity, Object[] updatedState, Object nextVersion) {
  189   		this.loadedState = updatedState;
  190   		
  191   		setLockMode(LockMode.WRITE);
  192   		
  193   		if ( getPersister().isVersioned() ) {
  194   			this.version = nextVersion;
  195   			getPersister().setPropertyValue( 
  196   					entity, 
  197   					getPersister().getVersionProperty(), 
  198   					nextVersion, 
  199   					entityMode 
  200   				);
  201   		}
  202   		
  203   		FieldInterceptionHelper.clearDirty( entity );
  204   	}
  205   
  206   	/**
  207   	 * After actually deleting a row, record the fact that the instance no longer
  208   	 * exists in the database
  209   	 */
  210   	public void postDelete() {
  211   		status = Status.GONE;
  212   		existsInDatabase = false;
  213   	}
  214   	
  215   	/**
  216   	 * After actually inserting a row, record the fact that the instance exists on the 
  217   	 * database (needed for identity-column key generation)
  218   	 */
  219   	public void postInsert() {
  220   		existsInDatabase = true;
  221   	}
  222   	
  223   	public boolean isNullifiable(boolean earlyInsert, SessionImplementor session) {
  224   		return getStatus() == Status.SAVING || (
  225   				earlyInsert ?
  226   						!isExistsInDatabase() :
  227   						session.getPersistenceContext().getNullifiableEntityKeys()
  228   							.contains( new EntityKey( getId(), getPersister(), entityMode ) )
  229   				);
  230   	}
  231   	
  232   	public Object getLoadedValue(String propertyName) {
  233   		int propertyIndex = ( (UniqueKeyLoadable) persister ).getPropertyIndex(propertyName);
  234   		return loadedState[propertyIndex];
  235   	}
  236   	
  237   	
  238   	public boolean requiresDirtyCheck(Object entity) {
  239   		
  240   		boolean isMutableInstance = 
  241   				status != Status.READ_ONLY && 
  242   				persister.isMutable();
  243   		
  244   		return isMutableInstance && (
  245   				getPersister().hasMutableProperties() ||
  246   				!FieldInterceptionHelper.isInstrumented( entity ) ||
  247   				FieldInterceptionHelper.extractFieldInterceptor( entity).isDirty()
  248   			);
  249   		
  250   	}
  251   
  252   	public void forceLocked(Object entity, Object nextVersion) {
  253   		version = nextVersion;
  254   		loadedState[ persister.getVersionProperty() ] = version;
  255   		setLockMode( LockMode.FORCE );
  256   		persister.setPropertyValue(
  257   				entity,
  258   		        getPersister().getVersionProperty(),
  259   		        nextVersion,
  260   		        entityMode
  261   		);
  262   	}
  263   
  264   	public void setReadOnly(boolean readOnly, Object entity) {
  265   		if (status!=Status.MANAGED && status!=Status.READ_ONLY) {
  266   			throw new HibernateException("instance was not in a valid state");
  267   		}
  268   		if (readOnly) {
  269   			setStatus(Status.READ_ONLY);
  270   			loadedState = null;
  271   		}
  272   		else {
  273   			setStatus(Status.MANAGED);
  274   			loadedState = getPersister().getPropertyValues(entity, entityMode);
  275   		}
  276   	}
  277   	
  278   	public String toString() {
  279   		return "EntityEntry" + 
  280   				MessageHelper.infoString(entityName, id) + 
  281   				'(' + status + ')';
  282   	}
  283   
  284   	public boolean isLoadedWithLazyPropertiesUnfetched() {
  285   		return loadedWithLazyPropertiesUnfetched;
  286   	}
  287   
  288   
  289   	/**
  290   	 * Custom serialization routine used during serialization of a
  291   	 * Session/PersistenceContext for increased performance.
  292   	 *
  293   	 * @param oos The stream to which we should write the serial data.
  294   	 * @throws java.io.IOException
  295   	 */
  296   	void serialize(ObjectOutputStream oos) throws IOException {
  297   		oos.writeObject( entityName );
  298   		oos.writeObject( id );
  299   		oos.writeObject( entityMode.toString() );
  300   		oos.writeObject( status.toString() );
  301   		// todo : potentially look at optimizing these two arrays
  302   		oos.writeObject( loadedState );
  303   		oos.writeObject( deletedState );
  304   		oos.writeObject( version );
  305   		oos.writeObject( lockMode.toString() );
  306   		oos.writeBoolean( existsInDatabase );
  307   		oos.writeBoolean( isBeingReplicated );
  308   		oos.writeBoolean( loadedWithLazyPropertiesUnfetched );
  309   	}
  310   
  311   	/**
  312   	 * Custom deserialization routine used during deserialization of a
  313   	 * Session/PersistenceContext for increased performance.
  314   	 *
  315   	 * @param ois The stream from which to read the entry.
  316   	 * @param session The session being deserialized.
  317   	 * @return The deserialized EntityEntry
  318   	 * @throws IOException
  319   	 * @throws ClassNotFoundException
  320   	 */
  321   	static EntityEntry deserialize(
  322   			ObjectInputStream ois,
  323   	        SessionImplementor session) throws IOException, ClassNotFoundException {
  324   		return new EntityEntry(
  325   				session.getFactory(),
  326   		        ( String ) ois.readObject(),
  327   				( Serializable ) ois.readObject(),
  328   	            EntityMode.parse( ( String ) ois.readObject() ),
  329   				Status.parse( ( String ) ois.readObject() ),
  330   	            ( Object[] ) ois.readObject(),
  331   	            ( Object[] ) ois.readObject(),
  332   	            ( Object ) ois.readObject(),
  333   	            LockMode.parse( ( String ) ois.readObject() ),
  334   	            ois.readBoolean(),
  335   	            ois.readBoolean(),
  336   	            ois.readBoolean()
  337   		);
  338   	}
  339   }

Save This Page
Home » Hibernate-3.3.2.GA » org.hibernate » engine » [javadoc | source]