DefaultReplicateEventListenerpublic class DefaultReplicateEventListener extends AbstractSaveEventListener implements org.hibernate.event.ReplicateEventListenerDefines the default replicate event listener used by Hibernate to replicate
entities in response to generated replicate events. |
Fields Summary |
---|
private static final Log | log |
Methods Summary |
---|
private void | cascadeAfterReplicate(java.lang.Object entity, org.hibernate.persister.entity.EntityPersister persister, org.hibernate.ReplicationMode replicationMode, org.hibernate.event.EventSource source)
source.getPersistenceContext().incrementCascadeLevel();
try {
new Cascade( CascadingAction.REPLICATE, Cascade.AFTER_UPDATE, source )
.cascade( persister, entity, replicationMode );
}
finally {
source.getPersistenceContext().decrementCascadeLevel();
}
| protected org.hibernate.engine.CascadingAction | getCascadeAction()
return CascadingAction.REPLICATE;
| protected boolean | isVersionIncrementDisabled()
return true;
| public void | onReplicate(org.hibernate.event.ReplicateEvent event)Handle the given replicate event.
final EventSource source = event.getSession();
if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) {
log.trace( "uninitialized proxy passed to replicate()" );
return;
}
Object entity = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
if ( source.getPersistenceContext().isEntryFor( entity ) ) {
log.trace( "ignoring persistent instance passed to replicate()" );
//hum ... should we cascade anyway? throw an exception? fine like it is?
return;
}
EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
// get the id from the object
/*if ( persister.isUnsaved(entity, source) ) {
throw new TransientObjectException("transient instance passed to replicate()");
}*/
Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
if ( id == null ) {
throw new TransientObjectException( "instance with null id passed to replicate()" );
}
final ReplicationMode replicationMode = event.getReplicationMode();
final Object oldVersion;
if ( replicationMode == ReplicationMode.EXCEPTION ) {
//always do an INSERT, and let it fail by constraint violation
oldVersion = null;
}
else {
//what is the version on the database?
oldVersion = persister.getCurrentVersion( id, source );
}
if ( oldVersion != null ) {
if ( log.isTraceEnabled() ) {
log.trace(
"found existing row for " +
MessageHelper.infoString( persister, id, source.getFactory() )
);
}
/// HHH-2378
final Object realOldVersion = persister.isVersioned() ? oldVersion : null;
boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(
entity,
realOldVersion,
persister.getVersion( entity, source.getEntityMode() ),
persister.getVersionType()
);
if ( canReplicate ) {
//will result in a SQL UPDATE:
performReplication( entity, id, realOldVersion, persister, replicationMode, source );
}
else {
//else do nothing (don't even reassociate object!)
log.trace( "no need to replicate" );
}
//TODO: would it be better to do a refresh from db?
}
else {
// no existing row - do an insert
if ( log.isTraceEnabled() ) {
log.trace(
"no existing row, replicating new instance " +
MessageHelper.infoString( persister, id, source.getFactory() )
);
}
final boolean regenerate = persister.isIdentifierAssignedByInsert(); // prefer re-generation of identity!
final EntityKey key = regenerate ?
null : new EntityKey( id, persister, source.getEntityMode() );
performSaveOrReplicate(
entity,
key,
persister,
regenerate,
replicationMode,
source,
true
);
}
| private void | performReplication(java.lang.Object entity, java.io.Serializable id, java.lang.Object version, org.hibernate.persister.entity.EntityPersister persister, org.hibernate.ReplicationMode replicationMode, org.hibernate.event.EventSource source)
if ( log.isTraceEnabled() ) {
log.trace(
"replicating changes to " +
MessageHelper.infoString( persister, id, source.getFactory() )
);
}
new OnReplicateVisitor( source, id, entity, true ).process( entity, persister );
source.getPersistenceContext().addEntity(
entity,
Status.MANAGED,
null,
new EntityKey( id, persister, source.getEntityMode() ),
version,
LockMode.NONE,
true,
persister,
true,
false
);
cascadeAfterReplicate( entity, persister, replicationMode, source );
| protected boolean | substituteValuesIfNecessary(java.lang.Object entity, java.io.Serializable id, java.lang.Object[] values, org.hibernate.persister.entity.EntityPersister persister, org.hibernate.engine.SessionImplementor source)
return false;
| protected boolean | visitCollectionsBeforeSave(java.lang.Object entity, java.io.Serializable id, java.lang.Object[] values, org.hibernate.type.Type[] types, org.hibernate.event.EventSource source)
//TODO: we use two visitors here, inefficient!
OnReplicateVisitor visitor = new OnReplicateVisitor( source, id, entity, false );
visitor.processEntityPropertyValues( values, types );
return super.visitCollectionsBeforeSave( entity, id, values, types, source );
|
|