📄 cascades.java
字号:
* a new transient instance or a previously persistent transient instance. * The strategy is determined by the <tt>unsaved-value</tt> attribute in * the mapping file. */ public static class IdentifierValue { private final Object value; protected IdentifierValue() { this.value = null; } /** * Assume the transient instance is newly instantiated if * its identifier is null or equal to <tt>value</tt> */ public IdentifierValue(Object value) { this.value = value; } /** * Does the given identifier belong to a new instance? */ public boolean isUnsaved(Serializable id) { if ( log.isTraceEnabled() ) log.trace("id unsaved-value: " + value); return id==null || value.equals(id); } } /** * Always assume the transient instance is newly instantiated */ public static final IdentifierValue SAVE_ANY = new IdentifierValue() { public final boolean isUnsaved(Serializable id) { log.trace("id unsaved-value strategy ANY"); return true; } }; /** * Never assume the transient instance is newly instantiated */ public static final IdentifierValue SAVE_NONE = new IdentifierValue() { public final boolean isUnsaved(Serializable id) { log.trace("id unsaved-value strategy NONE"); return false; } }; /** * Assume the transient instance is newly instantiated if the identifier * is null. */ public static final IdentifierValue SAVE_NULL = new IdentifierValue() { public final boolean isUnsaved(Serializable id) { log.trace("id unsaved-value strategy NULL"); return id==null; } }; /** * A strategy for determining if a version value is an version of * a new transient instance or a previously persistent transient instance. * The strategy is determined by the <tt>unsaved-value</tt> attribute in * the mapping file. */ public static class VersionValue { private final Object value; protected VersionValue() { this.value = null; } /** * Assume the transient instance is newly instantiated if * its version is null or equal to <tt>value</tt> * @param value value to compare to */ public VersionValue(Object value) { this.value = value; } /** * Does the given version belong to a new instance? * * @param version version to check * @return true is unsaved, false is saved, null is undefined */ public Boolean isUnsaved(Object version) throws MappingException { if ( log.isTraceEnabled() ) log.trace("version unsaved-value: " + value); return version==null || value.equals(version) ? Boolean.TRUE : Boolean.FALSE; } } /** * Assume the transient instance is newly instantiated if the version * is null, otherwise assume it is a detached instance. */ public static final VersionValue VERSION_SAVE_NULL = new VersionValue() { public final Boolean isUnsaved(Object version) { log.trace("version unsaved-value strategy NULL"); return version==null ? Boolean.TRUE : Boolean.FALSE; } }; /** * Assume the transient instance is newly instantiated if the version * is null, otherwise defer to the identifier unsaved-value. */ public static final VersionValue VERSION_UNDEFINED = new VersionValue() { public final Boolean isUnsaved(Object version) { log.trace("version unsaved-value strategy UNDEFINED"); return version==null ? Boolean.TRUE : null; } }; /** * Assume the transient instance is newly instantiated if the version * is negative, otherwise assume it is a detached instance. */ public static final VersionValue VERSION_NEGATIVE = new VersionValue() { public final Boolean isUnsaved(Object version) throws MappingException { log.trace("version unsaved-value strategy NEGATIVE"); if (version instanceof Number) { return ( (Number) version ).longValue() < 0l ? Boolean.TRUE : Boolean.FALSE; } else { throw new MappingException("unsaved-value NEGATIVE may only be used with short, int and long types"); } } }; /** * Cascade an action to the child or children */ private static void cascade( SessionImplementor session, Object child, Type type, CascadingAction action, CascadeStyle style, int cascadeTo, Object anything ) throws HibernateException { if (child!=null) { if ( type.isAssociationType() ) { if ( ( (AssociationType) type ).getForeignKeyDirection().cascadeNow(cascadeTo) ) { if ( type.isEntityType() || type.isObjectType() ) { /*if ( style.doCascade(session, child) )*/ action.cascade(session, child, anything); } else if ( type.isPersistentCollectionType() ) { final int cascadeVia; if ( cascadeTo==CASCADE_AFTER_INSERT_BEFORE_DELETE) { cascadeVia = CASCADE_AFTER_INSERT_BEFORE_DELETE_VIA_COLLECTION; } else { cascadeVia = cascadeTo; } PersistentCollectionType pctype = (PersistentCollectionType) type; CollectionPersister persister = session.getFactory().getCollectionPersister( pctype.getRole() ); Type elemType = persister.getElementType(); //cascade to current collection elements if ( elemType.isEntityType() || elemType.isObjectType() || elemType.isComponentType() ) { cascadeCollection(action, style, pctype, elemType, child, cascadeVia, session, anything); } } } } else if ( type.isComponentType() ) { AbstractComponentType componentType = (AbstractComponentType) type; Object[] children = componentType.getPropertyValues(child, session); Type[] types = componentType.getSubtypes(); for ( int i=0; i<types.length; i++ ) { CascadeStyle componentPropertyStyle = componentType.cascade(i); if ( componentPropertyStyle.doCascade(action) ) cascade( session, children[i], types[i], action, componentPropertyStyle, cascadeTo, anything ); } } } } /** * Cascade an action from the parent object to all its children */ public static void cascade( SessionImplementor session, ClassPersister persister, Object parent, Cascades.CascadingAction action, int cascadeTo) throws HibernateException { cascade(session, persister, parent, action, cascadeTo, null); } /** * Cascade an action from the parent object to all its children */ public static void cascade( SessionImplementor session, ClassPersister persister, Object parent, Cascades.CascadingAction action, int cascadeTo, Object anything) throws HibernateException { if ( persister.hasCascades() ) { // performance opt if ( log.isTraceEnabled() ) log.trace( "processing cascades for: " + persister.getClassName() ); Type[] types = persister.getPropertyTypes(); Cascades.CascadeStyle[] cascadeStyles = persister.getPropertyCascadeStyles(); for ( int i=0; i<types.length; i++) { CascadeStyle style = cascadeStyles[i]; if ( style.doCascade(action) ) { cascade( session, persister.getPropertyValue(parent,i), types[i], action, style, cascadeTo, anything ); } } if ( log.isTraceEnabled() ) log.trace( "done processing cascades for: " + persister.getClassName() ); } } /** * Cascade to the collection elements */ private static void cascadeCollection( CascadingAction action, CascadeStyle style, PersistentCollectionType collectionType, Type elemType, Object child, int cascadeVia, SessionImplementor session, Object anything ) throws HibernateException { if ( log.isTraceEnabled() ) log.trace( "cascading to collection: " + collectionType.getRole() ); Iterator iter = action.getCascadableChildrenIterator(collectionType, child); while ( iter.hasNext() ) cascade( session, iter.next(), elemType, action, style, cascadeVia, anything ); // handle orphaned entities!! if ( style.hasOrphanDelete() && action.deleteOrphans() && child instanceof PersistentCollection ) { // we can do the cast since orphan-delete does not apply to: // 1. newly instantiated collections // 2. arrays (we can't track orphans for detached arrays) deleteOrphans( (PersistentCollection) child, session ); } } /** * Delete any entities that were removed from the collection */ private static void deleteOrphans(PersistentCollection pc, SessionImplementor session) throws HibernateException { if ( pc.wasInitialized() ) { //can't be any orphans if it was not initialized! Iterator orphanIter = session.getOrphans(pc).iterator(); while ( orphanIter.hasNext() ) { Object orphan = orphanIter.next(); if (orphan!=null) session.delete(orphan); } } } /** * Iterate just the elements of the collection that are already there. Don't load * any new elements from the database. */ private static Iterator getLoadedElementsIterator(PersistentCollectionType collectionType, Object collection) { if ( collectionIsInitialized(collection) ) { // handles arrays and newly instantiated collections return collectionType.getElementsIterator(collection); } else { // does not handle arrays (thats ok, cos they can't be lazy) // or newly instantiated collections, so we can do the cast return ( (PersistentCollection) collection ).queuedAdditionIterator(); } } /** * Iterate all the collection elements, loading them from the database if necessary. */ private static Iterator getAllElementsIterator(PersistentCollectionType collectionType, Object collection) { return collectionType.getElementsIterator(collection); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -