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.action;
26
27 import org.hibernate.AssertionFailure;
28 import org.hibernate.HibernateException;
29 import org.hibernate.event.PostCollectionUpdateEvent;
30 import org.hibernate.event.PreCollectionUpdateEvent;
31 import org.hibernate.event.PreCollectionUpdateEventListener;
32 import org.hibernate.event.EventSource;
33 import org.hibernate.event.PostCollectionUpdateEventListener;
34 import org.hibernate.cache.CacheException;
35 import org.hibernate.collection.PersistentCollection;
36 import org.hibernate.engine.SessionImplementor;
37 import org.hibernate.persister.collection.CollectionPersister;
38 import org.hibernate.pretty.MessageHelper;
39
40 import java.io.Serializable;
41
42 public final class CollectionUpdateAction extends CollectionAction {
43
44 private final boolean emptySnapshot;
45
46 public CollectionUpdateAction(
47 final PersistentCollection collection,
48 final CollectionPersister persister,
49 final Serializable id,
50 final boolean emptySnapshot,
51 final SessionImplementor session)
52 throws CacheException {
53 super( persister, collection, id, session );
54 this.emptySnapshot = emptySnapshot;
55 }
56
57 public void execute() throws HibernateException {
58 final Serializable id = getKey();
59 final SessionImplementor session = getSession();
60 final CollectionPersister persister = getPersister();
61 final PersistentCollection collection = getCollection();
62 boolean affectedByFilters = persister.isAffectedByEnabledFilters(session);
63
64 preUpdate();
65
66 if ( !collection.wasInitialized() ) {
67 if ( !collection.hasQueuedOperations() ) throw new AssertionFailure( "no queued adds" );
68 //do nothing - we only need to notify the cache...
69 }
70 else if ( !affectedByFilters && collection.empty() ) {
71 if ( !emptySnapshot ) persister.remove( id, session );
72 }
73 else if ( collection.needsRecreate(persister) ) {
74 if (affectedByFilters) {
75 throw new HibernateException(
76 "cannot recreate collection while filter is enabled: " +
77 MessageHelper.collectionInfoString( persister, id, persister.getFactory() )
78 );
79 }
80 if ( !emptySnapshot ) persister.remove( id, session );
81 persister.recreate( collection, id, session );
82 }
83 else {
84 persister.deleteRows( collection, id, session );
85 persister.updateRows( collection, id, session );
86 persister.insertRows( collection, id, session );
87 }
88
89 getSession().getPersistenceContext()
90 .getCollectionEntry(collection)
91 .afterAction(collection);
92
93 evict();
94
95 postUpdate();
96
97 if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
98 getSession().getFactory().getStatisticsImplementor().
99 updateCollection( getPersister().getRole() );
100 }
101 }
102
103 private void preUpdate() {
104 PreCollectionUpdateEventListener[] preListeners = getSession().getListeners()
105 .getPreCollectionUpdateEventListeners();
106 if (preListeners.length > 0) {
107 PreCollectionUpdateEvent preEvent = new PreCollectionUpdateEvent(
108 getPersister(), getCollection(), ( EventSource ) getSession() );
109 for ( int i = 0; i < preListeners.length; i++ ) {
110 preListeners[i].onPreUpdateCollection( preEvent );
111 }
112 }
113 }
114
115 private void postUpdate() {
116 PostCollectionUpdateEventListener[] postListeners = getSession().getListeners()
117 .getPostCollectionUpdateEventListeners();
118 if (postListeners.length > 0) {
119 PostCollectionUpdateEvent postEvent = new PostCollectionUpdateEvent(
120 getPersister(), getCollection(), ( EventSource ) getSession() );
121 for ( int i = 0; i < postListeners.length; i++ ) {
122 postListeners[i].onPostUpdateCollection( postEvent );
123 }
124 }
125 }
126 }
127
128
129
130
131
132
133