KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > event > def > DefaultReplicateEventListener


1 //$Id: DefaultReplicateEventListener.java,v 1.14 2005/07/12 20:12:55 oneovthafew Exp $
2
package org.hibernate.event.def;
3
4 import org.hibernate.HibernateException;
5 import org.hibernate.TransientObjectException;
6 import org.hibernate.ReplicationMode;
7 import org.hibernate.LockMode;
8 import org.hibernate.engine.Cascade;
9 import org.hibernate.engine.CascadingAction;
10 import org.hibernate.engine.EntityKey;
11 import org.hibernate.engine.Status;
12 import org.hibernate.event.EventSource;
13 import org.hibernate.event.ReplicateEvent;
14 import org.hibernate.event.ReplicateEventListener;
15 import org.hibernate.engine.SessionImplementor;
16 import org.hibernate.persister.entity.EntityPersister;
17 import org.hibernate.pretty.MessageHelper;
18 import org.hibernate.type.Type;
19
20 import java.io.Serializable JavaDoc;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 /**
26  * Defines the default replicate event listener used by Hibernate to replicate
27  * entities in response to generated replicate events.
28  *
29  * @author Steve Ebersole
30  */

31 public class DefaultReplicateEventListener extends AbstractSaveEventListener implements ReplicateEventListener {
32
33     private static final Log log = LogFactory.getLog(DefaultReplicateEventListener.class);
34
35     /**
36      * Handle the given replicate event.
37      *
38      * @param event The replicate event to be handled.
39      * @throws HibernateException
40      */

41     public void onReplicate(ReplicateEvent event) throws HibernateException {
42
43         final EventSource source = event.getSession();
44         
45         if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) {
46             log.trace("uninitialized proxy passed to replicate()");
47             return;
48         }
49
50         Object JavaDoc entity = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
51
52         if ( source.getPersistenceContext().isEntryFor(entity) ) {
53             log.trace("ignoring persistent instance passed to replicate()");
54             //hum ... should we cascade anyway? throw an exception? fine like it is?
55
return;
56         }
57
58         EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
59         
60         // get the id from the object
61
/*if ( persister.isUnsaved(entity, source) ) {
62             throw new TransientObjectException("transient instance passed to replicate()");
63         }*/

64         Serializable JavaDoc id = persister.getIdentifier( entity, source.getEntityMode() );
65         if (id==null) {
66             throw new TransientObjectException("instance with null id passed to replicate()");
67         }
68
69         final ReplicationMode replicationMode = event.getReplicationMode();
70         
71         final Object JavaDoc oldVersion;
72         if ( replicationMode == ReplicationMode.EXCEPTION ) {
73             //always do an INSERT, and let it fail by constraint violation
74
oldVersion = null;
75         }
76         else {
77             //what is the version on the database?
78
oldVersion = persister.getCurrentVersion(id, source);
79         }
80
81         if ( oldVersion!=null ) {
82             //existing row - do an update if appropriate
83
if ( log.isTraceEnabled() ) {
84                 log.trace( "found existing row for " +
85                     MessageHelper.infoString( persister, id, source.getFactory() ) );
86             }
87
88             boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(
89                     entity,
90                     oldVersion,
91                     persister.getVersion( entity, source.getEntityMode() ),
92                     persister.getVersionType()
93             );
94
95             if (canReplicate) {
96                 //will result in a SQL UPDATE:
97
performReplication(entity, id, oldVersion, persister, replicationMode, source);
98             }
99             else {
100                 //else do nothing (don't even reassociate object!)
101
log.trace("no need to replicate");
102             }
103             
104             //TODO: would it be better to do a refresh from db?
105
}
106         else {
107             // no existing row - do an insert
108
if ( log.isTraceEnabled() ) {
109                 log.trace( "no existing row, replicating new instance " +
110                     MessageHelper.infoString( persister, id, source.getFactory() ) );
111             }
112
113             final boolean regenerate = persister.isIdentifierAssignedByInsert(); // prefer re-generation of identity!
114
final EntityKey key = regenerate ?
115                     null : new EntityKey( id, persister, source.getEntityMode() );
116
117             performSaveOrReplicate(
118                     entity,
119                     key,
120                     persister,
121                     regenerate,
122                     replicationMode,
123                     source
124             );
125
126         }
127     }
128
129     protected boolean visitCollectionsBeforeSave(Serializable JavaDoc id, Object JavaDoc[] values, Type[] types, EventSource source) {
130         //TODO: we use two visitors here, inefficient!
131
OnReplicateVisitor visitor = new OnReplicateVisitor(source, id, false);
132         visitor.processEntityPropertyValues(values, types);
133         return super.visitCollectionsBeforeSave(id, values, types, source);
134     }
135
136     protected boolean substituteValuesIfNecessary(
137             Object JavaDoc entity,
138             Serializable JavaDoc id,
139             Object JavaDoc[] values,
140             EntityPersister persister,
141             SessionImplementor source
142     ) {
143         return false;
144     }
145     
146     protected boolean isVersionIncrementDisabled() {
147         return true;
148     }
149     
150     private final void performReplication(
151             Object JavaDoc entity,
152             Serializable JavaDoc id,
153             Object JavaDoc version,
154             EntityPersister persister,
155             ReplicationMode replicationMode,
156             EventSource source)
157     throws HibernateException {
158
159         if ( log.isTraceEnabled() ) {
160             log.trace(
161                 "replicating changes to " +
162                 MessageHelper.infoString( persister, id, source.getFactory() )
163             );
164         }
165
166         new OnReplicateVisitor(source, id, true).process( entity, persister );
167
168         source.getPersistenceContext().addEntity(
169                 entity,
170                 Status.MANAGED,
171                 null,
172                 new EntityKey( id, persister, source.getEntityMode() ),
173                 version,
174                 LockMode.NONE,
175                 true,
176                 persister,
177                 true,
178                 false
179             );
180
181         cascadeAfterReplicate( entity, persister, replicationMode, source );
182     }
183
184     private void cascadeAfterReplicate(
185             Object JavaDoc entity,
186             EntityPersister persister,
187             ReplicationMode replicationMode,
188             EventSource source
189     ) {
190         source.getPersistenceContext().incrementCascadeLevel();
191         try {
192             new Cascade(CascadingAction.REPLICATE, Cascade.AFTER_UPDATE, source)
193                     .cascade(persister, entity, replicationMode);
194         }
195         finally {
196             source.getPersistenceContext().decrementCascadeLevel();
197         }
198     }
199
200     protected CascadingAction getCascadeAction() {
201         return CascadingAction.REPLICATE;
202     }
203 }
204
Popular Tags