fix the typing in ReplicationMode
and improve readability in DefaultReplicateEventListener even though they are deprecated Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
e351a00c19
commit
8aa37a9d85
|
@ -25,10 +25,9 @@ public enum ReplicationMode {
|
|||
*/
|
||||
EXCEPTION {
|
||||
@Override
|
||||
public boolean shouldOverwriteCurrentVersion(
|
||||
Object entity,
|
||||
Object currentVersion, Object newVersion,
|
||||
BasicType<Object> versionType) {
|
||||
public <T> boolean shouldOverwriteCurrentVersion(
|
||||
T currentVersion, T newVersion,
|
||||
BasicType<T> versionType) {
|
||||
throw new AssertionFailure( "should not be called" );
|
||||
}
|
||||
},
|
||||
|
@ -37,10 +36,9 @@ public enum ReplicationMode {
|
|||
*/
|
||||
IGNORE {
|
||||
@Override
|
||||
public boolean shouldOverwriteCurrentVersion(
|
||||
Object entity,
|
||||
Object currentVersion, Object newVersion,
|
||||
BasicType<Object> versionType) {
|
||||
public <T> boolean shouldOverwriteCurrentVersion(
|
||||
T currentVersion, T newVersion,
|
||||
BasicType<T> versionType) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
@ -49,10 +47,9 @@ public enum ReplicationMode {
|
|||
*/
|
||||
OVERWRITE {
|
||||
@Override
|
||||
public boolean shouldOverwriteCurrentVersion(
|
||||
Object entity,
|
||||
Object currentVersion, Object newVersion,
|
||||
BasicType<Object> versionType) {
|
||||
public <T> boolean shouldOverwriteCurrentVersion(
|
||||
T currentVersion, T newVersion,
|
||||
BasicType<T> versionType) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
@ -61,10 +58,9 @@ public enum ReplicationMode {
|
|||
*/
|
||||
LATEST_VERSION {
|
||||
@Override
|
||||
public boolean shouldOverwriteCurrentVersion(
|
||||
Object entity,
|
||||
Object currentVersion, Object newVersion,
|
||||
BasicType<Object> versionType) {
|
||||
public <T> boolean shouldOverwriteCurrentVersion(
|
||||
T currentVersion, T newVersion,
|
||||
BasicType<T> versionType) {
|
||||
// always overwrite non-versioned data (because we don't know which is newer)
|
||||
return versionType == null
|
||||
|| versionType.getJavaTypeDescriptor().getComparator()
|
||||
|
@ -82,9 +78,7 @@ public enum ReplicationMode {
|
|||
*
|
||||
* @return {@code true} indicates the data should be overwritten; {@code false} indicates it should not.
|
||||
*/
|
||||
public abstract boolean shouldOverwriteCurrentVersion(
|
||||
Object entity,
|
||||
Object currentVersion, Object newVersion,
|
||||
BasicType<Object> versionType);
|
||||
|
||||
public abstract <T> boolean shouldOverwriteCurrentVersion(
|
||||
T currentVersion, T newVersion,
|
||||
BasicType<T> versionType);
|
||||
}
|
||||
|
|
|
@ -24,10 +24,11 @@ import org.hibernate.event.spi.ReplicateEventListener;
|
|||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import static org.hibernate.pretty.MessageHelper.infoString;
|
||||
|
||||
/**
|
||||
* Defines the default replicate event listener used by Hibernate to replicate
|
||||
* entities in response to generated replicate events.
|
||||
|
@ -55,79 +56,72 @@ public class DefaultReplicateEventListener
|
|||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
if ( persistenceContext.reassociateIfUninitializedProxy( event.getObject() ) ) {
|
||||
LOG.trace( "Uninitialized proxy passed to replicate()" );
|
||||
return;
|
||||
}
|
||||
|
||||
Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
|
||||
|
||||
if ( persistenceContext.isEntryFor( entity ) ) {
|
||||
LOG.trace( "Ignoring persistent instance passed to replicate()" );
|
||||
//hum ... should we cascade anyway? throw an exception? fine like it is?
|
||||
return;
|
||||
else {
|
||||
final Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
|
||||
if ( persistenceContext.isEntryFor( entity ) ) {
|
||||
LOG.trace( "Ignoring persistent instance passed to replicate()" );
|
||||
//hum ... should we cascade anyway? throw an exception? fine like it is?
|
||||
}
|
||||
else {
|
||||
doReplicate( event, source, entity );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
|
||||
private void doReplicate(ReplicateEvent event, EventSource source, Object entity) {
|
||||
final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity);
|
||||
final ReplicationMode replicationMode = event.getReplicationMode();
|
||||
|
||||
// get the id from the object
|
||||
/*if ( persister.isUnsaved(entity, source) ) {
|
||||
throw new TransientObjectException("transient instance passed to replicate()");
|
||||
}*/
|
||||
Object id = persister.getIdentifier( entity, source );
|
||||
// get the id from the object - we accept almost anything at all,
|
||||
// except null (that is, even ids which look like they're unsaved)
|
||||
final Object id = persister.getIdentifier( entity, source );
|
||||
if ( id == null ) {
|
||||
throw new TransientObjectException( "instance with null id passed to replicate()" );
|
||||
}
|
||||
|
||||
final ReplicationMode replicationMode = event.getReplicationMode();
|
||||
|
||||
final Object oldVersion = replicationMode == ReplicationMode.EXCEPTION
|
||||
? null //always do an INSERT, and let it fail by constraint violation
|
||||
: persister.getCurrentVersion(id, source); //what is the version on the database?
|
||||
? null // always do an INSERT, and let it fail by constraint violation
|
||||
: persister.getCurrentVersion( id, source); // what is the version on the database?
|
||||
|
||||
if ( oldVersion != null ) {
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Found existing row for {0}",
|
||||
MessageHelper.infoString( persister, id, event.getFactory() )
|
||||
);
|
||||
LOG.tracev("Found existing row for {0}",
|
||||
infoString( persister, id, event.getFactory() ) );
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final BasicType<Object> versionType = (BasicType<Object>) persister.getVersionType();
|
||||
final Object realOldVersion = persister.isVersioned() ? oldVersion : null; /// HHH-2378
|
||||
boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(
|
||||
entity,
|
||||
realOldVersion,
|
||||
persister.getVersion( entity ),
|
||||
versionType
|
||||
);
|
||||
|
||||
// if can replicate, will result in a SQL UPDATE
|
||||
// else do nothing (don't even re-associate object!)
|
||||
if ( canReplicate ) {
|
||||
// If the entity has no version, getCurrentVersion() just returns
|
||||
// a meaningless value to indicate that the row exists (HHH-2378)
|
||||
final Object realOldVersion = persister.isVersioned() ? oldVersion : null;
|
||||
if ( shouldOverwrite( replicationMode,
|
||||
persister.getVersion( entity ), realOldVersion,
|
||||
persister.getVersionType() ) ) {
|
||||
// execute a SQL UPDATE
|
||||
performReplication( entity, id, realOldVersion, persister, replicationMode, source );
|
||||
}
|
||||
else if ( LOG.isTraceEnabled() ) {
|
||||
// do nothing (don't even re-associate 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
|
||||
// no existing row - execute a SQL INSERT
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"No existing row, replicating new instance {0}",
|
||||
MessageHelper.infoString( persister, id, event.getFactory() )
|
||||
);
|
||||
LOG.tracev( "No existing row, replicating new instance {0}",
|
||||
infoString( persister, id, event.getFactory() ) );
|
||||
}
|
||||
|
||||
final boolean regenerate = persister.isIdentifierAssignedByInsert(); // prefer re-generation of identity!
|
||||
final EntityKey key = regenerate ? null : source.generateEntityKey( id, persister );
|
||||
|
||||
performSaveOrReplicate( entity, key, persister, regenerate, replicationMode, source, false );
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> boolean shouldOverwrite(
|
||||
ReplicationMode replicationMode, Object entityVersion, Object realOldVersion, BasicType<T> versionType) {
|
||||
return replicationMode.shouldOverwriteCurrentVersion( (T) realOldVersion, (T) entityVersion, versionType );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean visitCollectionsBeforeSave(
|
||||
Object entity,
|
||||
|
@ -165,7 +159,8 @@ public class DefaultReplicateEventListener
|
|||
EventSource source) throws HibernateException {
|
||||
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev( "Replicating changes to {0}", MessageHelper.infoString( persister, id, source.getFactory() ) );
|
||||
LOG.tracev( "Replicating changes to {0}",
|
||||
infoString( persister, id, source.getFactory() ) );
|
||||
}
|
||||
|
||||
new OnReplicateVisitor( source, id, entity, true ).process( entity, persister );
|
||||
|
|
Loading…
Reference in New Issue