⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sessionimpl.java

📁 用Java实现的23个常用设计模式源代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
		// Sub-insertions should occur before containing insertion so		// Try to do the callback now		if ( persister.implementsLifecycle() ) {			log.debug("calling onSave()");			if ( ( (Lifecycle) object ).onSave(this) ) {				log.debug("insertion vetoed by onSave()");				return id;			}		}				return doSave(object, key, persister, false, useIdentityColumn, cascadeAction, anything);			}	private Serializable doSave(		final Object object, 		Key key,		final ClassPersister persister,		final boolean replicate,		final boolean useIdentityColumn,		final Cascades.CascadingAction cascadeAction, 		final Object anything) 	throws HibernateException {		if ( persister.implementsValidatable() ) ( (Validatable) object ).validate();				Serializable id = useIdentityColumn ? null : key.getIdentifier();		// Put a placeholder in entries, so we don't recurse back and try to save() the		// same object again. QUESTION: should this be done before onSave() is called?		// likewise, should it be done before onUpdate()?		addEntry(object, SAVING, null, id, null, LockMode.WRITE, useIdentityColumn, persister, false); //okay if id is null here		// cascade-save to many-to-one BEFORE the parent is saved		cascading++;		try {			Cascades.cascade(this, persister, object, cascadeAction, Cascades.CASCADE_BEFORE_INSERT_AFTER_DELETE, anything);		}		finally {			cascading--;		}		Object[] values = persister.getPropertyValues(object);		Type[] types = persister.getPropertyTypes();				boolean substitute = false;		if (!replicate) { 						substitute = interceptor.onSave( object, id, values, persister.getPropertyNames(), types );						//keep the existing version number in the case of replicate!			if ( persister.isVersioned() ) {				substitute = Versioning.seedVersion(					values, persister.getVersionProperty(), persister.getVersionType()				) || substitute;			}		}		else if ( persister.hasCollections() ) {			OnReplicateVisitor visitor = new OnReplicateVisitor(this, id);			visitor.processValues(values, types);		}		if (substitute) persister.setPropertyValues(object, values);		TypeFactory.deepCopy(values, types, persister.getPropertyUpdateability(), values);		nullifyTransientReferences(values, types, useIdentityColumn, object);		checkNullability(values, persister, false);		if (useIdentityColumn) {			id = persister.insert(values, object, this); 			//TODO: does not add newly inserted object to the second-level cache			key = new Key(id, persister);			checkUniqueness(key, object);			persister.setIdentifier(object, id);		}				Object version = Versioning.getVersion(values, persister);		addEntity(key, object);		addEntry(object, LOADED, values, id, version, LockMode.WRITE, useIdentityColumn, persister, replicate);		if (!useIdentityColumn) insertions.add( new ScheduledInsertion( id, values, object, persister, this ) );		// cascade-save to collections AFTER the collection owner was saved		cascading++;		try {			Cascades.cascade(this, persister, object, cascadeAction, Cascades.CASCADE_AFTER_INSERT_BEFORE_DELETE, anything);		}		finally {			cascading--;		}		return id;	}		boolean reassociateIfUninitializedProxy(Object value) throws MappingException {		if ( !Hibernate.isInitialized(value) ) {			HibernateProxy proxy = (HibernateProxy) value;			LazyInitializer li = HibernateProxyHelper.getLazyInitializer(proxy);			reassociateProxy(li, proxy);			return true;		}		else {			return false;		}	}		private void reassociateProxy(Object value, Serializable id) throws MappingException {		if (value instanceof HibernateProxy) {			HibernateProxy proxy = (HibernateProxy) value;			LazyInitializer li = HibernateProxyHelper.getLazyInitializer(proxy);			li.setIdentifier(id);			reassociateProxy(li, proxy);		}	}		private Object unproxy(Object maybeProxy) throws HibernateException {		if ( maybeProxy instanceof HibernateProxy ) {			HibernateProxy proxy = (HibernateProxy) maybeProxy;			LazyInitializer li = HibernateProxyHelper.getLazyInitializer(proxy);			if ( li.isUninitialized() ) throw new PersistentObjectException(				"object was an uninitialized proxy for: " + li.getPersistentClass().getName() 			);			return li.getImplementation(); //unwrap the object		}		else {			return maybeProxy;		}	}	private Object unproxyAndReassociate(Object maybeProxy) throws HibernateException {		if ( maybeProxy instanceof HibernateProxy ) {			HibernateProxy proxy = (HibernateProxy) maybeProxy;			LazyInitializer li = HibernateProxyHelper.getLazyInitializer(proxy);			reassociateProxy(li, proxy);			return li.getImplementation(); //initialize + unwrap the object		}		else {			return maybeProxy;		}	}	/**	 * associate a proxy that was instantiated by another session with this session	 */	private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) throws MappingException {		if ( li.getSession()!=this ) {			ClassPersister persister = getClassPersister( li.getPersistentClass() );			Key key = new Key( li.getIdentifier(), persister );			if ( !proxiesByKey.containsKey(key) ) proxiesByKey.put(key, proxy); // any earlier proxy takes precedence			HibernateProxyHelper.getLazyInitializer( proxy ).setSession(this);		}	}	private void nullifyTransientReferences(Object[] values, Type[] types, boolean earlyInsert, Object self) throws HibernateException {		for ( int i=0; i<types.length; i++ ) {			values[i] = nullifyTransientReferences( values[i], types[i], earlyInsert, self );		}	}	/**	 * Return null if the argument is an "unsaved" entity (ie. one with no existing database row),	 * or the input argument otherwise. This is how Hibernate avoids foreign key constraint	 * violations.	 */	private Object nullifyTransientReferences(Object value, Type type, boolean earlyInsert, Object self) throws HibernateException {		if ( value==null ) {			return null;		}		else if ( type.isEntityType() || type.isObjectType() ) {			return ( isUnsaved(value, earlyInsert, self) ) ? null : value;		}		else if ( type.isComponentType() ) {			AbstractComponentType actype = (AbstractComponentType) type;			Object[] subvalues = actype.getPropertyValues(value, this);			Type[] subtypes = actype.getSubtypes();			boolean substitute=false;			for ( int i=0; i<subvalues.length; i++ ) {				Object replacement = nullifyTransientReferences( subvalues[i], subtypes[i], earlyInsert, self );				if ( replacement!=subvalues[i] ) {					substitute=true;					subvalues[i]=replacement;				}			}			if (substitute) actype.setPropertyValues(value, subvalues);			return value;		}		else {			return value;		}	}	/**	 * determine if the object already exists in the database, using a	 * "best guess"	 */	private boolean isUnsaved(Object object, boolean earlyInsert, Object self) throws HibernateException {		if ( object instanceof HibernateProxy ) {			// if its an uninitialized proxy it can't be transient			LazyInitializer li = HibernateProxyHelper.getLazyInitializer( (HibernateProxy) object );			if ( li.getImplementation(this)==null ) {				return false;				// ie. we never have to null out a reference to				// an uninitialized proxy			}			else {				//unwrap it				object = li.getImplementation();			}		}		// if it was a reference to self, don't need to nullify		// unless we are using native id generation, in which		// case we definitely need to nullify		if (object==self) return earlyInsert;		// See if the entity is already bound to this session, if not look at the		// entity identifier and assume that the entity is persistent if the		// id is not "unsaved" (that is, we rely on foreign keys to keep		// database integrity)		EntityEntry e = getEntry(object);		if (e==null) {			return getPersister(object).isUnsaved(object);			/*if( persister.hasIdentifierPropertyOrEmbeddedCompositeIdentifier() ) {				Serializable id = persister.getIdentifier(object);				if (id!=null) {					// see if theres another object that *is* associated with the session for that id					e = getEntry( getEntity( new Key(id, persister) ) );					if (e==null) { // look at the id value						return persister.isUnsaved(object);					}					// else use the other object's entry....				}				else { // null id, so have to assume transient (because thats safer)					return true;				}			}			else { // can't determine the id, so assume transient (because thats safer)				return true;			}*/		}		return e.status==SAVING || (			earlyInsert ?			!e.existsInDatabase :			nullifiables.contains( new Key (e.id, e.persister) )		);	}	/**	 * Delete a persistent object	 */	public void delete(Object object) throws HibernateException {		if (object==null) throw new NullPointerException("attempted to delete null");		object = unproxyAndReassociate(object);		EntityEntry entry = getEntry(object);		final ClassPersister persister;		if (entry==null) {			log.trace("deleting a transient instance");			persister = getPersister(object);			Serializable id = persister.getIdentifier(object);			if (id==null) throw new TransientObjectException("the transient instance passed to delete() had a null identifier");			Object old = getEntity( new Key(id, persister) );			if (old!=null) throw new NonUniqueObjectException( id, persister.getMappedClass() );			new OnUpdateVisitor(this, id).process(object, persister);			addEntity( new Key(id, persister), object );			entry = addEntry(				object, LOADED,				persister.getPropertyValues(object),				id,				persister.getVersion(object),				LockMode.NONE,				true,				persister,				false			);			// not worth worrying about the proxy		}		else {			log.trace("deleting a persistent instance");			if ( entry.status==DELETED || entry.status==GONE ) {				log.trace("object was already deleted");				return;			}			persister = entry.persister;		}		if ( !persister.isMutable() ) throw new HibernateException(			"attempted to delete an object of immutable class: " +			MessageHelper.infoString(persister)		);				doDelete(object, entry, persister);			}			private void doDelete(Object object, EntityEntry entry, ClassPersister persister) throws HibernateException {		if ( log.isTraceEnabled() ) log.trace( "deleting " + MessageHelper.infoString(persister, entry.id) );		Type[] propTypes = persister.getPropertyTypes();		Object version = entry.version;//getCurrentVersion();		if ( entry.loadedState==null ) { //ie. the object came in from update()			entry.deletedState = persister.getPropertyValues(object);		}		else {			entry.deletedState = new Object[entry.loadedState.length];			TypeFactory.deepCopy(entry.loadedState, propTypes, persister.getPropertyUpdateability(), entry.deletedState);		}		interceptor.onDelete(object, entry.id, entry.deletedState, persister.getPropertyNames(), propTypes); //TODO: if an exception occurs, doesn't clean up entry.deletedState		entry.status = DELETED; // before any callbacks, etc, so subdeletions see that this deletion happened first				List deletionsByOnSave = null;		HashSet nullifiablesByOnSave = null;		try {			// after nullify, because we don't want to nullify references to subdeletions			// try to do callback + cascade, and before cascades, since this can veto			if ( persister.implementsLifecycle() ) {				HashSet oldNullifiables = (HashSet) nullifiables.clone();				ArrayList oldDeletions = (ArrayList) deletions.clone();				log.debug("calling onDelete()");				if ( ( (Lifecycle) object ).onDelete(this) ) {					//rollback deletion					entry.status = LOADED;					entry.deletedState = null;					log.debug("deletion vetoed by onDelete()");					return; //don't let it cascade				}				deletionsByOnSave = deletions.subList( oldDeletions.size(), deletions.size() );				deletions = oldDeletions;				nullifiablesByOnSave = nullifiables;				nullifiables = oldNullifiables;			}		}		catch (CallbackException ce) {			//rollback deletion			entry.status = LOADED;			entry.deletedState = null;			throw ce;		}				cascading++;		try {			// cascade-delete to collections BEFORE the collection owner is deleted			Cascades.cascade(this, persister, object, Cascades.ACTION_DELETE, Cascades.CASCADE_AFTER_INSERT_BEFORE_DELETE);		}		finally {			cascading--;		}		nullifyTransientReferences(entry.deletedState, propTypes, false, object);		checkNullability(entry.deletedState, persister, true);		nullifiables.add( new Key(entry.id, persister) );				ScheduledDeletion delete = new ScheduledDeletion(entry.id, version, object, persister, this);		deletions.add(delete); // Ensures that containing deletions happen before sub-deletions				if ( persister.implementsLifecycle() ) {			nullifiables.addAll(nullifiablesByOnSave);			deletions.addAll(deletionsByOnSave);		}				cascading++;		try {			// cascade-delete to many-to-one AFTER the parent was deleted			Cascades.cascade(this, persister, object, Cascades.ACTION_DELETE, Cascades.CASCADE_BEFORE_INSERT_AFTER_DELETE);		}		finally {			cascading--;		}	}		private static void checkNullability(Object[] values, ClassPersister persister, boolean isUpdate) 	throws PropertyValueException {		boolean[] nullability = persister.getPropertyNullability();		boolean[] checkability = isUpdate ? 			persister.getPropertyUpdateability() : 			persister.getPropertyInsertability();		for ( int i=0; i<values.length; i++ ) {			if ( !nullability[i] && checkability[i] && values[i]==null ) {				throw new PropertyValueException(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -