Merge remote-tracking branch 'upstream/master' into wip/6.0_merge_22

This commit is contained in:
Andrea Boriero 2020-01-22 19:34:38 +00:00
commit fd6866f029
44 changed files with 553 additions and 308 deletions

View File

@ -26,7 +26,7 @@ ext {
weldVersion = '3.0.0.Final' weldVersion = '3.0.0.Final'
javassistVersion = '3.24.0-GA' javassistVersion = '3.24.0-GA'
byteBuddyVersion = '1.10.2' byteBuddyVersion = '1.10.7'
agroalVersion = '1.7' agroalVersion = '1.7'

View File

@ -66,6 +66,30 @@ public class EntityDeleteAction extends EntityAction {
); );
} }
public Object getVersion() {
return version;
}
public boolean isCascadeDeleteEnabled() {
return isCascadeDeleteEnabled;
}
public Object[] getState() {
return state;
}
protected Object[] getNaturalIdValues() {
return naturalIdValues;
}
protected SoftLock getLock() {
return lock;
}
protected void setLock(SoftLock lock) {
this.lock = lock;
}
@Override @Override
public void execute() throws HibernateException { public void execute() throws HibernateException {
final Object id = getId(); final Object id = getId();
@ -125,7 +149,7 @@ public class EntityDeleteAction extends EntityAction {
} }
} }
private boolean preDelete() { protected boolean preDelete() {
boolean veto = false; boolean veto = false;
final EventListenerGroup<PreDeleteEventListener> listenerGroup = listenerGroup( EventType.PRE_DELETE ); final EventListenerGroup<PreDeleteEventListener> listenerGroup = listenerGroup( EventType.PRE_DELETE );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
@ -138,7 +162,7 @@ public class EntityDeleteAction extends EntityAction {
return veto; return veto;
} }
private void postDelete() { protected void postDelete() {
final EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_DELETE ); final EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_DELETE );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
return; return;
@ -155,7 +179,7 @@ public class EntityDeleteAction extends EntityAction {
} }
} }
private void postCommitDelete(boolean success) { protected void postCommitDelete(boolean success) {
final EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_DELETE ); final EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_DELETE );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
return; return;

View File

@ -27,7 +27,7 @@ import org.hibernate.stat.spi.StatisticsImplementor;
* *
* @see EntityInsertAction * @see EntityInsertAction
*/ */
public final class EntityIdentityInsertAction extends AbstractEntityInsertAction { public class EntityIdentityInsertAction extends AbstractEntityInsertAction {
private final boolean isDelayed; private final boolean isDelayed;
private final EntityKey delayedEntityKey; private final EntityKey delayedEntityKey;
@ -139,7 +139,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction
postCommitInsert( success ); postCommitInsert( success );
} }
private void postInsert() { protected void postInsert() {
final EventSource eventSource = eventSource(); final EventSource eventSource = eventSource();
if ( isDelayed ) { if ( isDelayed ) {
eventSource.getPersistenceContextInternal().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId ); eventSource.getPersistenceContextInternal().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId );
@ -161,7 +161,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction
} }
} }
private void postCommitInsert(boolean success) { protected void postCommitInsert(boolean success) {
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT ); final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
return; return;
@ -189,7 +189,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction
} }
} }
private boolean preInsert() { protected boolean preInsert() {
final EventListenerGroup<PreInsertEventListener> listenerGroup = listenerGroup( EventType.PRE_INSERT ); final EventListenerGroup<PreInsertEventListener> listenerGroup = listenerGroup( EventType.PRE_INSERT );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
// NO_VETO // NO_VETO
@ -212,6 +212,10 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction
return generatedId; return generatedId;
} }
protected void setGeneratedId(Serializable generatedId) {
this.generatedId = generatedId;
}
/** /**
* Access to the delayed entity key * Access to the delayed entity key
* *
@ -235,11 +239,15 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction
return entityKey != null ? entityKey : delayedEntityKey; return entityKey != null ? entityKey : delayedEntityKey;
} }
protected void setEntityKey(EntityKey entityKey) {
this.entityKey = entityKey;
}
private static DelayedPostInsertIdentifier generateDelayedPostInsertIdentifier() { private static DelayedPostInsertIdentifier generateDelayedPostInsertIdentifier() {
return new DelayedPostInsertIdentifier(); return new DelayedPostInsertIdentifier();
} }
private EntityKey generateDelayedEntityKey() { protected EntityKey generateDelayedEntityKey() {
if ( !isDelayed ) { if ( !isDelayed ) {
throw new AssertionFailure( "cannot request delayed entity-key for early-insert post-insert-id generation" ); throw new AssertionFailure( "cannot request delayed entity-key for early-insert post-insert-id generation" );
} }

View File

@ -33,7 +33,7 @@ import org.hibernate.stat.spi.StatisticsImplementor;
* *
* @see EntityIdentityInsertAction * @see EntityIdentityInsertAction
*/ */
public final class EntityInsertAction extends AbstractEntityInsertAction { public class EntityInsertAction extends AbstractEntityInsertAction {
private Object version; private Object version;
private Object cacheEntry; private Object cacheEntry;
@ -59,6 +59,22 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
this.version = version; this.version = version;
} }
public Object getVersion() {
return version;
}
public void setVersion(Object version) {
this.version = version;
}
protected Object getCacheEntry() {
return cacheEntry;
}
protected void setCacheEntry(Object cacheEntry) {
this.cacheEntry = cacheEntry;
}
@Override @Override
public boolean isEarlyInsert() { public boolean isEarlyInsert() {
return false; return false;
@ -140,7 +156,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
markExecuted(); markExecuted();
} }
private boolean cacheInsert(EntityPersister persister, Object ck) { protected boolean cacheInsert(EntityPersister persister, Object ck) {
SharedSessionContractImplementor session = getSession(); SharedSessionContractImplementor session = getSession();
try { try {
session.getEventListenerManager().cachePutStart(); session.getEventListenerManager().cachePutStart();
@ -151,7 +167,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
} }
} }
private void postInsert() { protected void postInsert() {
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_INSERT ); final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_INSERT );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
return; return;
@ -168,7 +184,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
} }
} }
private void postCommitInsert(boolean success) { protected void postCommitInsert(boolean success) {
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT ); final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
return; return;
@ -196,7 +212,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
} }
} }
private boolean preInsert() { protected boolean preInsert() {
boolean veto = false; boolean veto = false;
final EventListenerGroup<PreInsertEventListener> listenerGroup = listenerGroup( EventType.PRE_INSERT ); final EventListenerGroup<PreInsertEventListener> listenerGroup = listenerGroup( EventType.PRE_INSERT );
@ -230,7 +246,7 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
postCommitInsert( success ); postCommitInsert( success );
} }
private boolean cacheAfterInsert(EntityDataAccess cache, Object ck) { protected boolean cacheAfterInsert(EntityDataAccess cache, Object ck) {
SharedSessionContractImplementor session = getSession(); SharedSessionContractImplementor session = getSession();
final SessionEventListenerManager eventListenerManager = session.getEventListenerManager(); final SessionEventListenerManager eventListenerManager = session.getEventListenerManager();
try { try {
@ -253,8 +269,8 @@ public final class EntityInsertAction extends AbstractEntityInsertAction {
return false; return false;
} }
private boolean isCachePutEnabled(EntityPersister persister, SharedSessionContractImplementor session) { protected boolean isCachePutEnabled(EntityPersister persister, SharedSessionContractImplementor session) {
return persister.canWriteToCache() return persister.canWriteToCache()
&& !persister.isCacheInvalidationRequired() && !persister.isCacheInvalidationRequired()
&& session.getCacheMode().isPutEnabled(); && session.getCacheMode().isPutEnabled();

View File

@ -37,7 +37,7 @@ import org.hibernate.type.TypeHelper;
/** /**
* The action for performing entity updates. * The action for performing entity updates.
*/ */
public final class EntityUpdateAction extends EntityAction { public class EntityUpdateAction extends EntityAction {
private final Object[] state; private final Object[] state;
private final Object[] previousState; private final Object[] previousState;
private final Object previousVersion; private final Object previousVersion;
@ -110,6 +110,58 @@ public final class EntityUpdateAction extends EntityAction {
return persistenceContext.getNaturalIdSnapshot( id, persister ); return persistenceContext.getNaturalIdSnapshot( id, persister );
} }
public Object[] getState() {
return state;
}
public Object[] getPreviousState() {
return previousState;
}
public Object getPreviousVersion() {
return previousVersion;
}
public Object getNextVersion() {
return nextVersion;
}
public void setNextVersion(Object nextVersion) {
this.nextVersion = nextVersion;
}
public int[] getDirtyFields() {
return dirtyFields;
}
public boolean hasDirtyCollection() {
return hasDirtyCollection;
}
public Object getRowId() {
return rowId;
}
public Object[] getPreviousNaturalIdValues() {
return previousNaturalIdValues;
}
protected Object getCacheEntry() {
return cacheEntry;
}
protected void setCacheEntry(Object cacheEntry) {
this.cacheEntry = cacheEntry;
}
protected SoftLock getLock() {
return lock;
}
protected void setLock(SoftLock lock) {
this.lock = lock;
}
@Override @Override
public void execute() throws HibernateException { public void execute() throws HibernateException {
final Object id = getId(); final Object id = getId();
@ -221,7 +273,7 @@ public final class EntityUpdateAction extends EntityAction {
} }
} }
private boolean cacheUpdate(EntityPersister persister, Object previousVersion, Object ck) { protected boolean cacheUpdate(EntityPersister persister, Object previousVersion, Object ck) {
final SharedSessionContractImplementor session = getSession(); final SharedSessionContractImplementor session = getSession();
try { try {
session.getEventListenerManager().cachePutStart(); session.getEventListenerManager().cachePutStart();
@ -232,7 +284,7 @@ public final class EntityUpdateAction extends EntityAction {
} }
} }
private boolean preUpdate() { protected boolean preUpdate() {
boolean veto = false; boolean veto = false;
final EventListenerGroup<PreUpdateEventListener> listenerGroup = listenerGroup( EventType.PRE_UPDATE ); final EventListenerGroup<PreUpdateEventListener> listenerGroup = listenerGroup( EventType.PRE_UPDATE );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
@ -252,7 +304,7 @@ public final class EntityUpdateAction extends EntityAction {
return veto; return veto;
} }
private void postUpdate() { protected void postUpdate() {
final EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_UPDATE ); final EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_UPDATE );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
return; return;
@ -271,7 +323,7 @@ public final class EntityUpdateAction extends EntityAction {
} }
} }
private void postCommitUpdate(boolean success) { protected void postCommitUpdate(boolean success) {
final EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_UPDATE ); final EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_UPDATE );
if ( listenerGroup.isEmpty() ) { if ( listenerGroup.isEmpty() ) {
return; return;
@ -348,7 +400,7 @@ public final class EntityUpdateAction extends EntityAction {
postCommitUpdate( success ); postCommitUpdate( success );
} }
private boolean cacheAfterUpdate(EntityDataAccess cache, Object ck) { protected boolean cacheAfterUpdate(EntityDataAccess cache, Object ck) {
final SharedSessionContractImplementor session = getSession(); final SharedSessionContractImplementor session = getSession();
SessionEventListenerManager eventListenerManager = session.getEventListenerManager(); SessionEventListenerManager eventListenerManager = session.getEventListenerManager();
try { try {

View File

@ -17,7 +17,6 @@ import org.hibernate.action.internal.EntityInsertAction;
import org.hibernate.classic.Lifecycle; import org.hibernate.classic.Lifecycle;
import org.hibernate.engine.internal.Cascade; import org.hibernate.engine.internal.Cascade;
import org.hibernate.engine.internal.CascadePoint; import org.hibernate.engine.internal.CascadePoint;
import org.hibernate.engine.internal.ForeignKeys;
import org.hibernate.engine.internal.Versioning; import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.spi.CascadingAction; import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityEntry;
@ -49,10 +48,6 @@ public abstract class AbstractSaveEventListener
implements CallbackRegistryConsumer { implements CallbackRegistryConsumer {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractSaveEventListener.class ); private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractSaveEventListener.class );
public enum EntityState {
PERSISTENT, TRANSIENT, DETACHED, DELETED
}
private CallbackRegistry callbackRegistry; private CallbackRegistry callbackRegistry;
public void injectCallbackRegistry(CallbackRegistry callbackRegistry) { public void injectCallbackRegistry(CallbackRegistry callbackRegistry) {
@ -489,60 +484,4 @@ public abstract class AbstractSaveEventListener
protected abstract CascadingAction getCascadeAction(); protected abstract CascadingAction getCascadeAction();
/**
* Determine whether the entity is persistent, detached, or transient
*
* @param entity The entity to check
* @param entityName The name of the entity
* @param entry The entity's entry in the persistence context
* @param source The originating session.
*
* @return The state.
*/
protected EntityState getEntityState(
Object entity,
String entityName,
EntityEntry entry, //pass this as an argument only to avoid double looking
SessionImplementor source) {
if ( entry != null ) { // the object is persistent
//the entity is associated with the session, so check its status
if ( entry.getStatus() != Status.DELETED ) {
// do nothing for persistent instances
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Persistent instance of: {0}", getLoggableName( entityName, entity ) );
}
return EntityState.PERSISTENT;
}
// ie. e.status==DELETED
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Deleted instance of: {0}", getLoggableName( entityName, entity ) );
}
return EntityState.DELETED;
}
// the object is transient or detached
// the entity is not associated with the session, so
// try interceptor and unsaved-value
if ( ForeignKeys.isTransient( entityName, entity, getAssumedUnsaved(), source ) ) {
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Transient instance of: {0}", getLoggableName( entityName, entity ) );
}
return EntityState.TRANSIENT;
}
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Detached instance of: {0}", getLoggableName( entityName, entity ) );
}
return EntityState.DETACHED;
}
protected String getLoggableName(String entityName, Object entity) {
return entityName == null ? entity.getClass().getName() : entityName;
}
protected Boolean getAssumedUnsaved() {
return null;
}
} }

View File

@ -121,7 +121,7 @@ public abstract class AbstractVisitor {
* @param persister * @param persister
* @throws HibernateException * @throws HibernateException
*/ */
void process(Object object, EntityPersister persister) public void process(Object object, EntityPersister persister)
throws HibernateException { throws HibernateException {
processEntityPropertyValues( processEntityPropertyValues(
persister.getPropertyValues( object ), persister.getPropertyValues( object ),

View File

@ -145,13 +145,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
version = entityEntry.getVersion(); version = entityEntry.getVersion();
} }
/*if ( !persister.isMutable() ) { callbackRegistry.preRemove( entity );
throw new HibernateException(
"attempted to delete an object of immutable class: " +
MessageHelper.infoString(persister)
);
}*/
if ( invokeDeleteLifecycle( source, entity, persister ) ) { if ( invokeDeleteLifecycle( source, entity, persister ) ) {
return; return;
} }
@ -338,8 +332,6 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
} }
protected boolean invokeDeleteLifecycle(EventSource session, Object entity, EntityPersister persister) { protected boolean invokeDeleteLifecycle(EventSource session, Object entity, EntityPersister persister) {
callbackRegistry.preRemove( entity );
if ( persister.implementsLifecycle() ) { if ( persister.implementsLifecycle() ) {
LOG.debug( "Calling onDelete()" ); LOG.debug( "Calling onDelete()" );
if ( ( (Lifecycle) entity ).onDelete( session ) ) { if ( ( (Lifecycle) entity ).onDelete( session ) ) {

View File

@ -165,7 +165,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
} }
if ( entityState == null ) { if ( entityState == null ) {
entityState = getEntityState( entity, event.getEntityName(), entry, source ); entityState = EntityState.getEntityState( entity, event.getEntityName(), entry, source, false );
} }
switch ( entityState ) { switch ( entityState ) {
@ -182,7 +182,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
throw new ObjectDeletedException( throw new ObjectDeletedException(
"deleted instance passed to merge", "deleted instance passed to merge",
null, null,
getLoggableName( event.getEntityName(), entity ) EventUtil.getLoggableName( event.getEntityName(), entity )
); );
} }
} }
@ -537,11 +537,6 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
return CascadingActions.MERGE; return CascadingActions.MERGE;
} }
@Override
protected Boolean getAssumedUnsaved() {
return Boolean.FALSE;
}
/** /**
* Cascade behavior is redefined by this subclass, disable superclass behavior * Cascade behavior is redefined by this subclass, disable superclass behavior
*/ */

View File

@ -6,7 +6,6 @@
*/ */
package org.hibernate.event.internal; package org.hibernate.event.internal;
import java.io.Serializable;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.Map; import java.util.Map;
@ -24,7 +23,6 @@ import org.hibernate.event.spi.PersistEventListener;
import org.hibernate.id.ForeignGenerator; import org.hibernate.id.ForeignGenerator;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.event.spi.CallbackRegistry;
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer; import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper; import org.hibernate.pretty.MessageHelper;
@ -47,11 +45,6 @@ public class DefaultPersistEventListener
return CascadingActions.PERSIST; return CascadingActions.PERSIST;
} }
@Override
protected Boolean getAssumedUnsaved() {
return Boolean.TRUE;
}
/** /**
* Handle the given create event. * Handle the given create event.
* *
@ -99,7 +92,7 @@ public class DefaultPersistEventListener
} }
final EntityEntry entityEntry = source.getPersistenceContextInternal().getEntry( entity ); final EntityEntry entityEntry = source.getPersistenceContextInternal().getEntry( entity );
EntityState entityState = getEntityState( entity, entityName, entityEntry, source ); EntityState entityState = EntityState.getEntityState( entity, entityName, entityEntry, source, true );
if ( entityState == EntityState.DETACHED ) { if ( entityState == EntityState.DETACHED ) {
// JPA 2, in its version of a "foreign generated", allows the id attribute value // JPA 2, in its version of a "foreign generated", allows the id attribute value
// to be manually set by the user, even though this manual value is irrelevant. // to be manually set by the user, even though this manual value is irrelevant.
@ -116,7 +109,7 @@ public class DefaultPersistEventListener
LOG.debug( "Resetting entity id attribute to null for foreign generator" ); LOG.debug( "Resetting entity id attribute to null for foreign generator" );
} }
persister.setIdentifier( entity, null, source ); persister.setIdentifier( entity, null, source );
entityState = getEntityState( entity, entityName, entityEntry, source ); entityState = EntityState.getEntityState( entity, entityName, entityEntry, source, true );
} }
} }
@ -124,7 +117,7 @@ public class DefaultPersistEventListener
case DETACHED: { case DETACHED: {
throw new PersistentObjectException( throw new PersistentObjectException(
"detached entity passed to persist: " + "detached entity passed to persist: " +
getLoggableName( event.getEntityName(), entity ) EventUtil.getLoggableName( event.getEntityName(), entity )
); );
} }
case PERSISTENT: { case PERSISTENT: {
@ -146,7 +139,7 @@ public class DefaultPersistEventListener
throw new ObjectDeletedException( throw new ObjectDeletedException(
"deleted entity passed to persist", "deleted entity passed to persist",
null, null,
getLoggableName( event.getEntityName(), entity ) EventUtil.getLoggableName( event.getEntityName(), entity )
); );
} }
} }

View File

@ -69,10 +69,14 @@ public class DefaultPostLoadEventListener implements PostLoadEventListener, Call
session.getActionQueue().registerProcess( verifyVersion ); session.getActionQueue().registerProcess( verifyVersion );
} }
invokeLoadLifecycle(event, session);
}
protected void invokeLoadLifecycle(PostLoadEvent event, EventSource session) {
if ( event.getPersister().implementsLifecycle() ) { if ( event.getPersister().implementsLifecycle() ) {
//log.debug( "calling onLoad()" ); //log.debug( "calling onLoad()" );
( (Lifecycle) event.getEntity() ).onLoad( session, (Serializable) event.getId() ); ( (Lifecycle) event.getEntity() ).onLoad( session, (Serializable) event.getId() );
} }
} }
} }

View File

@ -80,11 +80,12 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener
} }
protected Object performSaveOrUpdate(SaveOrUpdateEvent event) { protected Object performSaveOrUpdate(SaveOrUpdateEvent event) {
EntityState entityState = getEntityState( EntityState entityState = EntityState.getEntityState(
event.getEntity(), event.getEntity(),
event.getEntityName(), event.getEntityName(),
event.getEntry(), event.getEntry(),
event.getSession() event.getSession(),
null
); );
switch ( entityState ) { switch ( entityState ) {

View File

@ -25,12 +25,12 @@ public class DirtyCollectionSearchVisitor extends AbstractVisitor {
private boolean dirty; private boolean dirty;
private boolean[] propertyVersionability; private boolean[] propertyVersionability;
DirtyCollectionSearchVisitor(EventSource session, boolean[] propertyVersionability) { public DirtyCollectionSearchVisitor(EventSource session, boolean[] propertyVersionability) {
super( session ); super( session );
this.propertyVersionability = propertyVersionability; this.propertyVersionability = propertyVersionability;
} }
boolean wasDirtyCollectionFound() { public boolean wasDirtyCollectionFound() {
return dirty; return dirty;
} }

View File

@ -0,0 +1,71 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.event.internal;
import org.hibernate.engine.internal.ForeignKeys;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
public enum EntityState {
PERSISTENT, TRANSIENT, DETACHED, DELETED;
static final CoreMessageLogger LOG = CoreLogging.messageLogger( EntityState.class );
/**
* Determine whether the entity is persistent, detached, or transient
*
* @param entity The entity to check
* @param entityName The name of the entity
* @param entry The entity's entry in the persistence context
* @param source The originating session.
*
* @return The state.
*/
public static EntityState getEntityState(
Object entity,
String entityName,
EntityEntry entry, //pass this as an argument only to avoid double looking
SessionImplementor source,
Boolean assumedUnsaved) {
if ( entry != null ) { // the object is persistent
//the entity is associated with the session, so check its status
if ( entry.getStatus() != Status.DELETED ) {
// do nothing for persistent instances
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Persistent instance of: {0}", EventUtil.getLoggableName( entityName, entity ) );
}
return PERSISTENT;
}
// ie. e.status==DELETED
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Deleted instance of: {0}", EventUtil.getLoggableName( entityName, entity ) );
}
return DELETED;
}
// the object is transient or detached
// the entity is not associated with the session, so
// try interceptor and unsaved-value
if ( ForeignKeys.isTransient( entityName, entity, assumedUnsaved, source ) ) {
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Transient instance of: {0}", EventUtil.getLoggableName( entityName, entity ) );
}
return TRANSIENT;
}
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Detached instance of: {0}", EventUtil.getLoggableName( entityName, entity ) );
}
return DETACHED;
}
}

View File

@ -0,0 +1,13 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.event.internal;
public class EventUtil {
public static String getLoggableName(String entityName, Object entity) {
return entityName == null ? entity.getClass().getName() : entityName;
}
}

View File

@ -30,7 +30,7 @@ public class EvictVisitor extends AbstractVisitor {
private Object owner; private Object owner;
EvictVisitor(EventSource session, Object owner) { public EvictVisitor(EventSource session, Object owner) {
super(session); super(session);
this.owner = owner; this.owner = owner;
} }

View File

@ -23,7 +23,7 @@ import org.hibernate.type.CollectionType;
public class FlushVisitor extends AbstractVisitor { public class FlushVisitor extends AbstractVisitor {
private Object owner; private Object owner;
FlushVisitor(EventSource session, Object owner) { public FlushVisitor(EventSource session, Object owner) {
super(session); super(session);
this.owner = owner; this.owner = owner;
} }

View File

@ -77,7 +77,7 @@ import org.jboss.logging.Logger;
* *
* @author Gail Badner * @author Gail Badner
*/ */
class MergeContext implements Map { public class MergeContext implements Map {
private static final Logger LOG = Logger.getLogger( MergeContext.class ); private static final Logger LOG = Logger.getLogger( MergeContext.class );
private final EventSource session; private final EventSource session;
@ -101,7 +101,7 @@ class MergeContext implements Map {
// key is a merge entity; // key is a merge entity;
// value is a flag indicating if the merge entity is currently in the merge process. // value is a flag indicating if the merge entity is currently in the merge process.
MergeContext(EventSource session, EntityCopyObserver entityCopyObserver){ public MergeContext(EventSource session, EntityCopyObserver entityCopyObserver){
this.session = session; this.session = session;
this.entityCopyObserver = entityCopyObserver; this.entityCopyObserver = entityCopyObserver;
} }
@ -226,7 +226,7 @@ class MergeContext implements Map {
* managed entity associated with <code>mergeEntity</code> * managed entity associated with <code>mergeEntity</code>
* @throws IllegalStateException if internal cross-references are out of sync, * @throws IllegalStateException if internal cross-references are out of sync,
*/ */
/* package-private */ Object put(Object mergeEntity, Object managedEntity, boolean isOperatedOn) { public Object put(Object mergeEntity, Object managedEntity, boolean isOperatedOn) {
if ( mergeEntity == null || managedEntity == null ) { if ( mergeEntity == null || managedEntity == null ) {
throw new NullPointerException( "null merge and managed entities are not supported by " + getClass().getName() ); throw new NullPointerException( "null merge and managed entities are not supported by " + getClass().getName() );
} }
@ -347,7 +347,7 @@ class MergeContext implements Map {
* @throws NullPointerException if mergeEntity is null * @throws NullPointerException if mergeEntity is null
* @throws IllegalStateException if this MergeContext does not contain a a cross-reference for mergeEntity * @throws IllegalStateException if this MergeContext does not contain a a cross-reference for mergeEntity
*/ */
/* package-private */ void setOperatedOn(Object mergeEntity, boolean isOperatedOn) { public void setOperatedOn(Object mergeEntity, boolean isOperatedOn) {
if ( mergeEntity == null ) { if ( mergeEntity == null ) {
throw new NullPointerException( "null entities are not supported by " + getClass().getName() ); throw new NullPointerException( "null entities are not supported by " + getClass().getName() );
} }

View File

@ -28,7 +28,7 @@ public class OnReplicateVisitor extends ReattachVisitor {
private boolean isUpdate; private boolean isUpdate;
OnReplicateVisitor(EventSource session, Object key, Object owner, boolean isUpdate) { public OnReplicateVisitor(EventSource session, Object key, Object owner, boolean isUpdate) {
super( session, key, owner ); super( session, key, owner );
this.isUpdate = isUpdate; this.isUpdate = isUpdate;
} }

View File

@ -24,7 +24,7 @@ import org.hibernate.type.CollectionType;
*/ */
public class OnUpdateVisitor extends ReattachVisitor { public class OnUpdateVisitor extends ReattachVisitor {
OnUpdateVisitor(EventSource session, Object key, Object owner) { public OnUpdateVisitor(EventSource session, Object key, Object owner) {
super( session, key, owner ); super( session, key, owner );
} }

View File

@ -19,7 +19,6 @@ import org.hibernate.type.EntityType;
*/ */
public abstract class ProxyVisitor extends AbstractVisitor { public abstract class ProxyVisitor extends AbstractVisitor {
public ProxyVisitor(EventSource session) { public ProxyVisitor(EventSource session) {
super(session); super(session);
} }

View File

@ -40,11 +40,11 @@ public class WrapVisitor extends ProxyVisitor {
this.id = id; this.id = id;
} }
boolean isSubstitutionRequired() { public boolean isSubstitutionRequired() {
return substitute; return substitute;
} }
WrapVisitor(EventSource session) { public WrapVisitor(EventSource session) {
super( session ); super( session );
} }
@ -150,7 +150,7 @@ public class WrapVisitor extends ProxyVisitor {
} }
@Override @Override
void process(Object object, EntityPersister persister) throws HibernateException { public void process(Object object, EntityPersister persister) throws HibernateException {
final Object[] values = persister.getPropertyValues( object ); final Object[] values = persister.getPropertyValues( object );
final Type[] types = persister.getPropertyTypes(); final Type[] types = persister.getPropertyTypes();
processEntityPropertyValues( values, types ); processEntityPropertyValues( values, types );

View File

@ -160,7 +160,7 @@ public class AttributeNodeImpl<J>
final SubGraphImplementor<? extends J> previous = subGraphMap.put( subType, (SubGraphImplementor) subGraph ); final SubGraphImplementor<? extends J> previous = subGraphMap.put( subType, (SubGraphImplementor) subGraph );
if ( previous != null ) { if ( previous != null ) {
log.debugf( "Adding sub-graph [%s] over-wrote existing [%]", subGraph, previous ); log.debugf( "Adding sub-graph [%s] over-wrote existing [%s]", subGraph, previous );
} }
} }

View File

@ -51,6 +51,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.transaction.internal.TransactionImpl; import org.hibernate.engine.transaction.internal.TransactionImpl;
import org.hibernate.engine.transaction.spi.TransactionImplementor; import org.hibernate.engine.transaction.spi.TransactionImplementor;
import org.hibernate.id.uuid.StandardRandomStrategy; import org.hibernate.id.uuid.StandardRandomStrategy;
import org.hibernate.jpa.QueryHints;
import org.hibernate.jpa.internal.util.FlushModeTypeHelper; import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.procedure.ProcedureCall; import org.hibernate.procedure.ProcedureCall;

View File

@ -156,7 +156,7 @@ import org.jboss.logging.Logger;
* @author Steve Ebersole * @author Steve Ebersole
* @author Chris Cranford * @author Chris Cranford
*/ */
public final class SessionFactoryImpl implements SessionFactoryImplementor { public class SessionFactoryImpl implements SessionFactoryImplementor {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SessionFactoryImpl.class ); private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SessionFactoryImpl.class );
private final String name; private final String name;
@ -1081,7 +1081,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
return null; return null;
} }
static class SessionBuilderImpl<T extends SessionBuilder> implements SessionBuilderImplementor<T>, SessionCreationOptions { public static class SessionBuilderImpl<T extends SessionBuilder> implements SessionBuilderImplementor<T>, SessionCreationOptions {
private static final Logger log = CoreLogging.logger( SessionBuilderImpl.class ); private static final Logger log = CoreLogging.logger( SessionBuilderImpl.class );
private final SessionFactoryImpl sessionFactory; private final SessionFactoryImpl sessionFactory;
@ -1105,7 +1105,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
//todo : expose setting //todo : expose setting
private SessionOwnerBehavior sessionOwnerBehavior = SessionOwnerBehavior.LEGACY_NATIVE; private SessionOwnerBehavior sessionOwnerBehavior = SessionOwnerBehavior.LEGACY_NATIVE;
SessionBuilderImpl(SessionFactoryImpl sessionFactory) { public SessionBuilderImpl(SessionFactoryImpl sessionFactory) {
this.sessionFactory = sessionFactory; this.sessionFactory = sessionFactory;
// set up default builder values... // set up default builder values...

View File

@ -164,7 +164,7 @@ import static org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_STORE_MODE;
* @author Chris Cranford * @author Chris Cranford
* @author Sanne Grinovero * @author Sanne Grinovero
*/ */
public final class SessionImpl public class SessionImpl
extends AbstractSessionImpl extends AbstractSessionImpl
implements SessionImplementor, EventSource { implements SessionImplementor, EventSource {
private static final EntityManagerMessageLogger log = HEMLogging.messageLogger( SessionImpl.class ); private static final EntityManagerMessageLogger log = HEMLogging.messageLogger( SessionImpl.class );
@ -532,13 +532,13 @@ public final class SessionImpl
} }
} }
private void checkNoUnresolvedActionsBeforeOperation() { protected void checkNoUnresolvedActionsBeforeOperation() {
if ( persistenceContext.getCascadeLevel() == 0 && actionQueue.hasUnresolvedEntityInsertActions() ) { if ( persistenceContext.getCascadeLevel() == 0 && actionQueue.hasUnresolvedEntityInsertActions() ) {
throw new IllegalStateException( "There are delayed insert actions before operation as cascade level 0." ); throw new IllegalStateException( "There are delayed insert actions before operation as cascade level 0." );
} }
} }
private void checkNoUnresolvedActionsAfterOperation() { protected void checkNoUnresolvedActionsAfterOperation() {
if ( persistenceContext.getCascadeLevel() == 0 ) { if ( persistenceContext.getCascadeLevel() == 0 ) {
actionQueue.checkNoUnresolvedActionsAfterOperation(); actionQueue.checkNoUnresolvedActionsAfterOperation();
} }
@ -2815,7 +2815,7 @@ public final class SessionImpl
} }
} }
private CacheMode determineAppropriateLocalCacheMode(Map<String, Object> localProperties) { protected CacheMode determineAppropriateLocalCacheMode(Map<String, Object> localProperties) {
CacheRetrieveMode retrieveMode = null; CacheRetrieveMode retrieveMode = null;
CacheStoreMode storeMode = null; CacheStoreMode storeMode = null;
if ( localProperties != null ) { if ( localProperties != null ) {

View File

@ -113,7 +113,7 @@ public class Column implements Selectable, Serializable, Cloneable {
final int lastLetter = StringHelper.lastIndexOfLetter( name ); final int lastLetter = StringHelper.lastIndexOfLetter( name );
final String suffix = AliasConstantsHelper.get( uniqueInteger ); final String suffix = AliasConstantsHelper.get( uniqueInteger );
String alias = name; String alias = name.toLowerCase( Locale.ROOT );
if ( lastLetter == -1 ) { if ( lastLetter == -1 ) {
alias = "column"; alias = "column";
} }

View File

@ -95,6 +95,9 @@ import org.hibernate.persister.walking.spi.CompositionDefinition;
import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.persister.walking.spi.EntityDefinition;
import org.hibernate.pretty.MessageHelper; import org.hibernate.pretty.MessageHelper;
import org.hibernate.sql.Alias; import org.hibernate.sql.Alias;
import org.hibernate.sql.Insert;
import org.hibernate.sql.Update;
import org.hibernate.sql.Delete;
import org.hibernate.sql.SelectFragment; import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.SimpleSelect; import org.hibernate.sql.SimpleSelect;
import org.hibernate.sql.Template; import org.hibernate.sql.Template;
@ -2429,4 +2432,16 @@ public abstract class AbstractCollectionPersister
public CollectionSemantics getCollectionSemantics() { public CollectionSemantics getCollectionSemantics() {
return collectionSemantics; return collectionSemantics;
} }
protected Insert createInsert() {
return new Insert( getFactory().getJdbcServices().getDialect() );
}
protected Update createUpdate() {
return new Update( getFactory().getJdbcServices().getDialect() );
}
protected Delete createDelete() {
return new Delete();
}
} }

View File

@ -66,8 +66,7 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
*/ */
@Override @Override
protected String generateDeleteString() { protected String generateDeleteString() {
final Delete delete = new Delete() final Delete delete = createDelete().setTableName( qualifiedTableName )
.setTableName( qualifiedTableName )
.addPrimaryKeyColumns( keyColumnNames ); .addPrimaryKeyColumns( keyColumnNames );
if ( hasWhere ) { if ( hasWhere ) {
@ -86,8 +85,7 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
*/ */
@Override @Override
protected String generateInsertRowString() { protected String generateInsertRowString() {
final Insert insert = new Insert( getDialect() ) final Insert insert = createInsert().setTableName( qualifiedTableName )
.setTableName( qualifiedTableName )
.addColumns( keyColumnNames ); .addColumns( keyColumnNames );
if ( hasIdentifier ) { if ( hasIdentifier ) {
@ -114,8 +112,7 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
*/ */
@Override @Override
protected String generateUpdateRowString() { protected String generateUpdateRowString() {
final Update update = new Update( getDialect() ) final Update update = createUpdate().setTableName( qualifiedTableName );
.setTableName( qualifiedTableName );
//if ( !elementIsFormula ) { //if ( !elementIsFormula ) {
update.addColumns( elementColumnNames, elementColumnIsSettable, elementColumnWriters ); update.addColumns( elementColumnNames, elementColumnIsSettable, elementColumnWriters );
@ -149,7 +146,7 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
*/ */
@Override @Override
protected String generateDeleteRowString() { protected String generateDeleteRowString() {
final Delete delete = new Delete().setTableName( qualifiedTableName ); final Delete delete = createDelete().setTableName( qualifiedTableName );
if ( hasIdentifier ) { if ( hasIdentifier ) {
delete.addPrimaryKeyColumns( new String[] {identifierColumnName} ); delete.addPrimaryKeyColumns( new String[] {identifierColumnName} );

View File

@ -72,10 +72,8 @@ public class OneToManyPersister extends AbstractCollectionPersister {
*/ */
@Override @Override
protected String generateDeleteString() { protected String generateDeleteString() {
final Update update = new Update( getDialect() ) final Update update = createUpdate().setTableName( qualifiedTableName )
.setTableName( qualifiedTableName ) .addColumns( keyColumnNames, "null" );
.addColumns( keyColumnNames, "null" )
.addPrimaryKeyColumns( keyColumnNames );
if ( hasIndex && !indexContainsFormula ) { if ( hasIndex && !indexContainsFormula ) {
for ( int i = 0 ; i < indexColumnNames.length ; i++ ) { for ( int i = 0 ; i < indexColumnNames.length ; i++ ) {
@ -85,6 +83,8 @@ public class OneToManyPersister extends AbstractCollectionPersister {
} }
} }
update.addPrimaryKeyColumns( keyColumnNames );
if ( hasWhere ) { if ( hasWhere ) {
update.setWhere( sqlWhereString ); update.setWhere( sqlWhereString );
} }
@ -101,8 +101,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
*/ */
@Override @Override
protected String generateInsertRowString() { protected String generateInsertRowString() {
final Update update = new Update( getDialect() ) final Update update = createUpdate().setTableName( qualifiedTableName )
.setTableName( qualifiedTableName )
.addColumns( keyColumnNames ); .addColumns( keyColumnNames );
if ( hasIndex && !indexContainsFormula ) { if ( hasIndex && !indexContainsFormula ) {
@ -128,11 +127,8 @@ public class OneToManyPersister extends AbstractCollectionPersister {
*/ */
@Override @Override
protected String generateUpdateRowString() { protected String generateUpdateRowString() {
final Update update = new Update( getDialect() ).setTableName( qualifiedTableName ); final Update update = createUpdate().setTableName( qualifiedTableName );
update.addPrimaryKeyColumns( elementColumnNames, elementColumnIsSettable, elementColumnWriters );
if ( hasIdentifier ) {
update.addPrimaryKeyColumns( new String[] {identifierColumnName} );
}
if ( hasIndex && !indexContainsFormula ) { if ( hasIndex && !indexContainsFormula ) {
for ( int i = 0 ; i < indexColumnNames.length ; i++ ) { for ( int i = 0 ; i < indexColumnNames.length ; i++ ) {
if ( indexColumnIsSettable[i] ) { if ( indexColumnIsSettable[i] ) {
@ -141,6 +137,12 @@ public class OneToManyPersister extends AbstractCollectionPersister {
} }
} }
update.addPrimaryKeyColumns( elementColumnNames, elementColumnIsSettable, elementColumnWriters );
if ( hasIdentifier ) {
update.addPrimaryKeyColumns( new String[] {identifierColumnName} );
}
return update.toStatementString(); return update.toStatementString();
} }
@ -150,8 +152,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
*/ */
@Override @Override
protected String generateDeleteRowString() { protected String generateDeleteRowString() {
final Update update = new Update( getDialect() ) final Update update = createUpdate().setTableName( qualifiedTableName )
.setTableName( qualifiedTableName )
.addColumns( keyColumnNames, "null" ); .addColumns( keyColumnNames, "null" );
if ( hasIndex && !indexContainsFormula ) { if ( hasIndex && !indexContainsFormula ) {

View File

@ -410,15 +410,15 @@ public abstract class AbstractEntityPersister
public abstract int getSubclassTableSpan(); public abstract int getSubclassTableSpan();
protected abstract int getTableSpan(); public abstract int getTableSpan();
protected abstract boolean isTableCascadeDeleteEnabled(int j); public abstract boolean isTableCascadeDeleteEnabled(int j);
protected abstract String getTableName(int j); public abstract String getTableName(int j);
protected abstract String[] getKeyColumns(int j); public abstract String[] getKeyColumns(int j);
protected abstract boolean isPropertyOfTable(int property, int j); public abstract boolean isPropertyOfTable(int property, int j);
protected abstract int[] getPropertyTableNumbersInSelect(); protected abstract int[] getPropertyTableNumbersInSelect();
@ -449,19 +449,19 @@ public abstract class AbstractEntityPersister
} }
} }
protected String getDiscriminatorAlias() { public String getDiscriminatorAlias() {
return DISCRIMINATOR_ALIAS; return DISCRIMINATOR_ALIAS;
} }
protected String getDiscriminatorFormulaTemplate() { public String getDiscriminatorFormulaTemplate() {
return null; return null;
} }
protected boolean isInverseTable(int j) { public boolean isInverseTable(int j) {
return false; return false;
} }
protected boolean isNullableTable(int j) { public boolean isNullableTable(int j) {
return false; return false;
} }
@ -485,7 +485,7 @@ public abstract class AbstractEntityPersister
return rootTableKeyColumnNames; return rootTableKeyColumnNames;
} }
protected String[] getSQLUpdateByRowIdStrings() { public String[] getSQLUpdateByRowIdStrings() {
if ( sqlUpdateByRowIdString == null ) { if ( sqlUpdateByRowIdString == null ) {
throw new AssertionFailure( "no update by row id" ); throw new AssertionFailure( "no update by row id" );
} }
@ -495,7 +495,7 @@ public abstract class AbstractEntityPersister
return result; return result;
} }
protected String[] getSQLLazyUpdateByRowIdStrings() { public String[] getSQLLazyUpdateByRowIdStrings() {
if ( sqlLazyUpdateByRowIdString == null ) { if ( sqlLazyUpdateByRowIdString == null ) {
throw new AssertionFailure( "no update by row id" ); throw new AssertionFailure( "no update by row id" );
} }
@ -505,52 +505,64 @@ public abstract class AbstractEntityPersister
return result; return result;
} }
protected String getSQLSnapshotSelectString() { public String getSQLSnapshotSelectString() {
return sqlSnapshotSelectString; return sqlSnapshotSelectString;
} }
protected String getSQLLazySelectString(String fetchGroup) { public String getSQLLazySelectString(String fetchGroup) {
return sqlLazySelectStringsByFetchGroup.get( fetchGroup ); return sqlLazySelectStringsByFetchGroup.get( fetchGroup );
} }
protected String[] getSQLDeleteStrings() { public String[] getSQLDeleteStrings() {
return sqlDeleteStrings; return sqlDeleteStrings;
} }
protected String[] getSQLInsertStrings() { public String[] getSQLInsertStrings() {
return sqlInsertStrings; return sqlInsertStrings;
} }
protected String[] getSQLUpdateStrings() { public String[] getSQLUpdateStrings() {
return sqlUpdateStrings; return sqlUpdateStrings;
} }
protected String[] getSQLLazyUpdateStrings() { public String[] getSQLLazyUpdateStrings() {
return sqlLazyUpdateStrings; return sqlLazyUpdateStrings;
} }
public ExecuteUpdateResultCheckStyle[] getInsertResultCheckStyles() {
return insertResultCheckStyles;
}
public ExecuteUpdateResultCheckStyle[] getUpdateResultCheckStyles() {
return updateResultCheckStyles;
}
public ExecuteUpdateResultCheckStyle[] getDeleteResultCheckStyles() {
return deleteResultCheckStyles;
}
/** /**
* The query that inserts a row, letting the database generate an id * The query that inserts a row, letting the database generate an id
* *
* @return The IDENTITY-based insertion query. * @return The IDENTITY-based insertion query.
*/ */
protected String getSQLIdentityInsertString() { public String getSQLIdentityInsertString() {
return sqlIdentityInsertString; return sqlIdentityInsertString;
} }
protected String getVersionSelectString() { public String getVersionSelectString() {
return sqlVersionSelectString; return sqlVersionSelectString;
} }
protected boolean isInsertCallable(int j) { public boolean isInsertCallable(int j) {
return insertCallable[j]; return insertCallable[j];
} }
protected boolean isUpdateCallable(int j) { public boolean isUpdateCallable(int j) {
return updateCallable[j]; return updateCallable[j];
} }
protected boolean isDeleteCallable(int j) { public boolean isDeleteCallable(int j) {
return deleteCallable[j]; return deleteCallable[j];
} }
@ -577,7 +589,7 @@ public abstract class AbstractEntityPersister
* *
* @return Array of booleans indicating which table require updating. * @return Array of booleans indicating which table require updating.
*/ */
protected boolean[] getTableUpdateNeeded(final int[] dirtyProperties, boolean hasDirtyCollection) { public boolean[] getTableUpdateNeeded(final int[] dirtyProperties, boolean hasDirtyCollection) {
if ( dirtyProperties == null ) { if ( dirtyProperties == null ) {
return getTableHasColumns(); // for objects that came in via update() return getTableHasColumns(); // for objects that came in via update()
@ -611,15 +623,15 @@ public abstract class AbstractEntityPersister
return rowIdName != null; return rowIdName != null;
} }
protected boolean[][] getPropertyColumnUpdateable() { public boolean[][] getPropertyColumnUpdateable() {
return propertyColumnUpdateable; return propertyColumnUpdateable;
} }
protected boolean[][] getPropertyColumnInsertable() { public boolean[][] getPropertyColumnInsertable() {
return propertyColumnInsertable; return propertyColumnInsertable;
} }
protected boolean[] getPropertySelectable() { public boolean[] getPropertySelectable() {
return propertySelectable; return propertySelectable;
} }
@ -1719,11 +1731,11 @@ public abstract class AbstractEntityPersister
return rootTableKeyColumnReaderTemplates; return rootTableKeyColumnReaderTemplates;
} }
protected int getIdentifierColumnSpan() { public int getIdentifierColumnSpan() {
return identifierColumnSpan; return identifierColumnSpan;
} }
protected String[] getIdentifierAliases() { public String[] getIdentifierAliases() {
return identifierAliases; return identifierAliases;
} }
@ -1731,7 +1743,7 @@ public abstract class AbstractEntityPersister
return versionColumnName; return versionColumnName;
} }
protected String getVersionedTableName() { public String getVersionedTableName() {
return getTableName( 0 ); return getTableName( 0 );
} }
@ -1864,7 +1876,7 @@ public abstract class AbstractEntityPersister
/** /**
* Generate the SQL that selects the version number by id * Generate the SQL that selects the version number by id
*/ */
protected String generateSelectVersionString() { public String generateSelectVersionString() {
SimpleSelect select = new SimpleSelect( getFactory().getDialect() ) SimpleSelect select = new SimpleSelect( getFactory().getDialect() )
.setTableName( getVersionedTableName() ); .setTableName( getVersionedTableName() );
if ( isVersioned() ) { if ( isVersioned() ) {
@ -1883,11 +1895,11 @@ public abstract class AbstractEntityPersister
return propertyUniqueness; return propertyUniqueness;
} }
protected String generateInsertGeneratedValuesSelectString() { public String generateInsertGeneratedValuesSelectString() {
return generateGeneratedValuesSelectString( GenerationTiming.INSERT ); return generateGeneratedValuesSelectString( GenerationTiming.INSERT );
} }
protected String generateUpdateGeneratedValuesSelectString() { public String generateUpdateGeneratedValuesSelectString() {
return generateGeneratedValuesSelectString( GenerationTiming.ALWAYS ); return generateGeneratedValuesSelectString( GenerationTiming.ALWAYS );
} }
@ -1969,7 +1981,7 @@ public abstract class AbstractEntityPersister
return frag.toFragmentString(); return frag.toFragmentString();
} }
protected String generateSnapshotSelectString() { public String generateSnapshotSelectString() {
//TODO: should we use SELECT .. FOR UPDATE? //TODO: should we use SELECT .. FOR UPDATE?
@ -2065,8 +2077,7 @@ public abstract class AbstractEntityPersister
} }
private String generateVersionIncrementUpdateString() { private String generateVersionIncrementUpdateString() {
Update update = new Update( getFactory().getDialect() ); Update update = createUpdate().setTableName( getTableName( 0 ) );
update.setTableName( getTableName( 0 ) );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) { if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
update.setComment( "forced version increment" ); update.setComment( "forced version increment" );
} }
@ -2345,11 +2356,11 @@ public abstract class AbstractEntityPersister
return propertyColumnWriters[i]; return propertyColumnWriters[i];
} }
protected int getPropertyColumnSpan(int i) { public int getPropertyColumnSpan(int i) {
return propertyColumnSpans[i]; return propertyColumnSpans[i];
} }
protected boolean hasFormulaProperties() { public boolean hasFormulaProperties() {
return hasFormulaProperties; return hasFormulaProperties;
} }
@ -2709,28 +2720,20 @@ public abstract class AbstractEntityPersister
return true; return true;
} }
protected String generateUpdateString(boolean[] includeProperty, int j, boolean useRowId) { public String generateUpdateString(boolean[] includeProperty, int j, boolean useRowId) {
return generateUpdateString( includeProperty, j, null, useRowId ); return generateUpdateString( includeProperty, j, null, useRowId );
} }
/** /**
* Generate the SQL that updates a row by id (and version) * Generate the SQL that updates a row by id (and version)
*/ */
protected String generateUpdateString( public String generateUpdateString(
final boolean[] includeProperty, final boolean[] includeProperty,
final int j, final int j,
final Object[] oldFields, final Object[] oldFields,
final boolean useRowId) { final boolean useRowId) {
Update update = new Update( getFactory().getDialect() ).setTableName( getTableName( j ) ); Update update = createUpdate().setTableName( getTableName( j ) );
// select the correct row by either pk or rowid
if ( useRowId ) {
update.addPrimaryKeyColumns( new String[] {rowIdName} ); //TODO: eventually, rowIdName[j]
}
else {
update.addPrimaryKeyColumns( getKeyColumns( j ) );
}
boolean hasColumns = false; boolean hasColumns = false;
for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) { for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
@ -2759,6 +2762,14 @@ public abstract class AbstractEntityPersister
} }
} }
// select the correct row by either pk or rowid
if ( useRowId ) {
update.addPrimaryKeyColumns( new String[] {rowIdName} ); //TODO: eventually, rowIdName[j]
}
else {
update.addPrimaryKeyColumns( getKeyColumns( j ) );
}
if ( j == 0 && isVersioned() && entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.VERSION ) { if ( j == 0 && isVersioned() && entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.VERSION ) {
// this is the root (versioned) table, and we are using version-based // this is the root (versioned) table, and we are using version-based
// optimistic locking; if we are not updating the version, also don't // optimistic locking; if we are not updating the version, also don't
@ -2810,29 +2821,28 @@ public abstract class AbstractEntityPersister
return hasColumns ? update.toStatementString() : null; return hasColumns ? update.toStatementString() : null;
} }
protected final boolean checkVersion(final boolean[] includeProperty) { public final boolean checkVersion(final boolean[] includeProperty) {
return includeProperty[getVersionProperty()] return includeProperty[getVersionProperty()]
|| entityMetamodel.isVersionGenerated(); || entityMetamodel.isVersionGenerated();
} }
protected String generateInsertString(boolean[] includeProperty, int j) { public String generateInsertString(boolean[] includeProperty, int j) {
return generateInsertString( false, includeProperty, j ); return generateInsertString( false, includeProperty, j );
} }
protected String generateInsertString(boolean identityInsert, boolean[] includeProperty) { public String generateInsertString(boolean identityInsert, boolean[] includeProperty) {
return generateInsertString( identityInsert, includeProperty, 0 ); return generateInsertString( identityInsert, includeProperty, 0 );
} }
/** /**
* Generate the SQL that inserts a row * Generate the SQL that inserts a row
*/ */
protected String generateInsertString(boolean identityInsert, boolean[] includeProperty, int j) { public String generateInsertString(boolean identityInsert, boolean[] includeProperty, int j) {
// todo : remove the identityInsert param and variations; // todo : remove the identityInsert param and variations;
// identity-insert strings are now generated from generateIdentityInsertString() // identity-insert strings are now generated from generateIdentityInsertString()
Insert insert = new Insert( getFactory().getDialect() ) Insert insert = createInsert().setTableName( getTableName( j ) );
.setTableName( getTableName( j ) );
// add normal properties // add normal properties
for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) { for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
@ -2925,7 +2935,7 @@ public abstract class AbstractEntityPersister
* *
* @return The insert SQL statement string * @return The insert SQL statement string
*/ */
protected String generateIdentityInsertString(boolean[] includeProperty) { public String generateIdentityInsertString(boolean[] includeProperty) {
Insert insert = identityDelegate.prepareIdentifierGeneratingInsert(); Insert insert = identityDelegate.prepareIdentifierGeneratingInsert();
insert.setTableName( getTableName( 0 ) ); insert.setTableName( getTableName( 0 ) );
@ -2992,9 +3002,8 @@ public abstract class AbstractEntityPersister
/** /**
* Generate the SQL that deletes a row by id (and version) * Generate the SQL that deletes a row by id (and version)
*/ */
protected String generateDeleteString(int j) { public String generateDeleteString(int j) {
final Delete delete = new Delete() final Delete delete = createDelete().setTableName( getTableName( j ) )
.setTableName( getTableName( j ) )
.addPrimaryKeyColumns( getKeyColumns( j ) ); .addPrimaryKeyColumns( getKeyColumns( j ) );
if ( j == 0 ) { if ( j == 0 ) {
delete.setVersionColumnName( getVersionColumnName() ); delete.setVersionColumnName( getVersionColumnName() );
@ -3005,7 +3014,7 @@ public abstract class AbstractEntityPersister
return delete.toStatementString(); return delete.toStatementString();
} }
protected int dehydrate( public int dehydrate(
Serializable id, Serializable id,
Object[] fields, Object[] fields,
boolean[] includeProperty, boolean[] includeProperty,
@ -3020,7 +3029,7 @@ public abstract class AbstractEntityPersister
/** /**
* Marshall the fields of a persistent instance to a prepared statement * Marshall the fields of a persistent instance to a prepared statement
*/ */
protected int dehydrate( public int dehydrate(
final Object id, final Object id,
final Object[] fields, final Object[] fields,
final Object rowId, final Object rowId,
@ -3201,11 +3210,11 @@ public abstract class AbstractEntityPersister
} }
} }
protected boolean useInsertSelectIdentity() { public boolean useInsertSelectIdentity() {
return !useGetGeneratedKeys() && getFactory().getDialect().getIdentityColumnSupport().supportsInsertSelectIdentity(); return !useGetGeneratedKeys() && getFactory().getDialect().getIdentityColumnSupport().supportsInsertSelectIdentity();
} }
protected boolean useGetGeneratedKeys() { public boolean useGetGeneratedKeys() {
return getFactory().getSessionFactoryOptions().isGetGeneratedKeysEnabled(); return getFactory().getSessionFactoryOptions().isGetGeneratedKeysEnabled();
} }
@ -3219,7 +3228,7 @@ public abstract class AbstractEntityPersister
* This form is used for PostInsertIdentifierGenerator-style ids (IDENTITY, * This form is used for PostInsertIdentifierGenerator-style ids (IDENTITY,
* select, etc). * select, etc).
*/ */
protected Serializable insert( public Serializable insert(
final Object[] fields, final Object[] fields,
final boolean[] notNull, final boolean[] notNull,
String sql, String sql,
@ -3272,7 +3281,7 @@ public abstract class AbstractEntityPersister
* This for is used for all non-root tables as well as the root table * This for is used for all non-root tables as well as the root table
* in cases where the identifier value is known before the insert occurs. * in cases where the identifier value is known before the insert occurs.
*/ */
protected void insert( public void insert(
final Object id, final Object id,
final Object[] fields, final Object[] fields,
final boolean[] notNull, final boolean[] notNull,
@ -3375,7 +3384,7 @@ public abstract class AbstractEntityPersister
/** /**
* Perform an SQL UPDATE or SQL INSERT * Perform an SQL UPDATE or SQL INSERT
*/ */
protected void updateOrInsert( public void updateOrInsert(
final Object id, final Object id,
final Object[] fields, final Object[] fields,
final Object[] oldFields, final Object[] oldFields,
@ -3429,7 +3438,7 @@ public abstract class AbstractEntityPersister
private BasicBatchKey updateBatchKey; private BasicBatchKey updateBatchKey;
protected boolean update( public boolean update(
final Object id, final Object id,
final Object[] fields, final Object[] fields,
final Object[] oldFields, final Object[] oldFields,
@ -3577,7 +3586,7 @@ public abstract class AbstractEntityPersister
/** /**
* Perform an SQL DELETE * Perform an SQL DELETE
*/ */
protected void delete( public void delete(
final Object id, final Object id,
final Object version, final Object version,
final int j, final int j,
@ -3934,8 +3943,7 @@ public abstract class AbstractEntityPersister
int span = getTableSpan(); int span = getTableSpan();
String[] deleteStrings = new String[span]; String[] deleteStrings = new String[span];
for ( int j = span - 1; j >= 0; j-- ) { for ( int j = span - 1; j >= 0; j-- ) {
Delete delete = new Delete() Delete delete = createDelete().setTableName( getTableName( j ) )
.setTableName( getTableName( j ) )
.addPrimaryKeyColumns( getKeyColumns( j ) ); .addPrimaryKeyColumns( getKeyColumns( j ) );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) { if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
delete.setComment( "delete " + getEntityName() + " [" + j + "]" ); delete.setComment( "delete " + getEntityName() + " [" + j + "]" );
@ -4539,7 +4547,7 @@ public abstract class AbstractEntityPersister
&& filterHelper.isAffectedBy( loadQueryInfluencers.getEnabledFilters() ); && filterHelper.isAffectedBy( loadQueryInfluencers.getEnabledFilters() );
} }
protected final boolean isAllNull(Object[] array, int tableNumber) { public final boolean isAllNull(Object[] array, int tableNumber) {
for ( int i = 0; i < array.length; i++ ) { for ( int i = 0; i < array.length; i++ ) {
if ( isPropertyOfTable( i, tableNumber ) && array[i] != null ) { if ( isPropertyOfTable( i, tableNumber ) && array[i] != null ) {
return false; return false;
@ -4556,7 +4564,7 @@ public abstract class AbstractEntityPersister
* Transform the array of property indexes to an array of booleans, * Transform the array of property indexes to an array of booleans,
* true when the property is dirty * true when the property is dirty
*/ */
protected final boolean[] getPropertiesToUpdate(final int[] dirtyProperties, final boolean hasDirtyCollection) { public final boolean[] getPropertiesToUpdate(final int[] dirtyProperties, final boolean hasDirtyCollection) {
final boolean[] propsToUpdate = new boolean[entityMetamodel.getPropertySpan()]; final boolean[] propsToUpdate = new boolean[entityMetamodel.getPropertySpan()];
final boolean[] updateability = getPropertyUpdateability(); //no need to check laziness, dirty checking handles that final boolean[] updateability = getPropertyUpdateability(); //no need to check laziness, dirty checking handles that
for ( int j = 0; j < dirtyProperties.length; j++ ) { for ( int j = 0; j < dirtyProperties.length; j++ ) {
@ -4580,7 +4588,7 @@ public abstract class AbstractEntityPersister
* Transform the array of property indexes to an array of booleans, * Transform the array of property indexes to an array of booleans,
* true when the property is insertable and non-null * true when the property is insertable and non-null
*/ */
protected boolean[] getPropertiesToInsert(Object[] fields) { public boolean[] getPropertiesToInsert(Object[] fields) {
boolean[] notNull = new boolean[fields.length]; boolean[] notNull = new boolean[fields.length];
boolean[] insertable = getPropertyInsertability(); boolean[] insertable = getPropertyInsertability();
for ( int i = 0; i < fields.length; i++ ) { for ( int i = 0; i < fields.length; i++ ) {
@ -4654,7 +4662,7 @@ public abstract class AbstractEntityPersister
* Which properties appear in the SQL update? * Which properties appear in the SQL update?
* (Initialized, updateable ones!) * (Initialized, updateable ones!)
*/ */
protected boolean[] getPropertyUpdateability(Object entity) { public boolean[] getPropertyUpdateability(Object entity) {
return hasUninitializedLazyProperties( entity ) return hasUninitializedLazyProperties( entity )
? getNonLazyPropertyUpdateability() ? getNonLazyPropertyUpdateability()
: getPropertyUpdateability(); : getPropertyUpdateability();
@ -4891,7 +4899,7 @@ public abstract class AbstractEntityPersister
return entityMetamodel.isMutable(); return entityMetamodel.isMutable();
} }
protected final boolean isModifiableEntity(EntityEntry entry) { public final boolean isModifiableEntity(EntityEntry entry) {
return ( entry == null ? isMutable() : entry.isModifiableEntity() ); return ( entry == null ? isMutable() : entry.isModifiableEntity() );
} }
@ -4936,7 +4944,7 @@ public abstract class AbstractEntityPersister
return entityMetamodel.isDynamicInsert(); return entityMetamodel.isDynamicInsert();
} }
protected boolean hasEmbeddedCompositeIdentifier() { public boolean hasEmbeddedCompositeIdentifier() {
return entityMetamodel.getIdentifierProperty().isEmbedded(); return entityMetamodel.getIdentifierProperty().isEmbedded();
} }
@ -5298,7 +5306,7 @@ public abstract class AbstractEntityPersister
return false; return false;
} }
protected int getPropertySpan() { public int getPropertySpan() {
return entityMetamodel.getPropertySpan(); return entityMetamodel.getPropertySpan();
} }
@ -6553,4 +6561,16 @@ public abstract class AbstractEntityPersister
// } // }
// }; // };
} }
protected Insert createInsert() {
return new Insert( getFactory().getJdbcServices().getDialect() );
}
protected Update createUpdate() {
return new Update( getFactory().getJdbcServices().getDialect() );
}
protected Delete createDelete() {
return new Delete();
}
} }

View File

@ -788,12 +788,12 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
} }
@Override @Override
protected boolean isNullableTable(int j) { public boolean isNullableTable(int j) {
return isNullableTable[j]; return isNullableTable[j];
} }
@Override @Override
protected boolean isInverseTable(int j) { public boolean isInverseTable(int j) {
return isInverseTable[j]; return isInverseTable[j];
} }
@ -851,7 +851,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
return getDiscriminatorColumnName(); return getDiscriminatorColumnName();
} }
protected String getDiscriminatorAlias() { public String getDiscriminatorAlias() {
return discriminatorAlias; return discriminatorAlias;
} }
@ -871,19 +871,19 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
} }
protected String getTableName(int j) { public String getTableName(int j) {
return naturalOrderTableNames[j]; return naturalOrderTableNames[j];
} }
protected String[] getKeyColumns(int j) { public String[] getKeyColumns(int j) {
return naturalOrderTableKeyColumns[j]; return naturalOrderTableKeyColumns[j];
} }
protected boolean isTableCascadeDeleteEnabled(int j) { public boolean isTableCascadeDeleteEnabled(int j) {
return naturalOrderCascadeDeleteEnabled[j]; return naturalOrderCascadeDeleteEnabled[j];
} }
protected boolean isPropertyOfTable(int property, int j) { public boolean isPropertyOfTable(int property, int j) {
return naturalOrderPropertyTableNumbers[property] == j; return naturalOrderPropertyTableNumbers[property] == j;
} }
@ -980,14 +980,14 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
} }
@Override @Override
public String filterFragment(String alias) { protected String filterFragment(String alias) {
return hasWhere() return hasWhere()
? " and " + getSQLWhereString( generateFilterConditionAlias( alias ) ) ? " and " + getSQLWhereString( generateFilterConditionAlias( alias ) )
: ""; : "";
} }
@Override @Override
public String filterFragment(String alias, Set<String> treatAsDeclarations) { protected String filterFragment(String alias, Set<String> treatAsDeclarations) {
return filterFragment( alias ); return filterFragment( alias );
} }

View File

@ -465,7 +465,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
} }
} }
protected boolean isInverseTable(int j) { public boolean isInverseTable(int j) {
return isInverseTable[j]; return isInverseTable[j];
} }
@ -485,11 +485,11 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
return discriminatorColumnReaderTemplate; return discriminatorColumnReaderTemplate;
} }
protected String getDiscriminatorAlias() { public String getDiscriminatorAlias() {
return discriminatorAlias; return discriminatorAlias;
} }
protected String getDiscriminatorFormulaTemplate() { public String getDiscriminatorFormulaTemplate() {
return discriminatorFormulaTemplate; return discriminatorFormulaTemplate;
} }
@ -540,19 +540,19 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
return discriminatorFormula; return discriminatorFormula;
} }
protected String getTableName(int j) { public String getTableName(int j) {
return qualifiedTableNames[j]; return qualifiedTableNames[j];
} }
protected String[] getKeyColumns(int j) { public String[] getKeyColumns(int j) {
return keyColumnNames[j]; return keyColumnNames[j];
} }
protected boolean isTableCascadeDeleteEnabled(int j) { public boolean isTableCascadeDeleteEnabled(int j) {
return cascadeDeleteEnabled[j]; return cascadeDeleteEnabled[j];
} }
protected boolean isPropertyOfTable(int property, int j) { public boolean isPropertyOfTable(int property, int j) {
return propertyTableNumbers[property] == j; return propertyTableNumbers[property] == j;
} }
@ -567,7 +567,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
} }
@Override @Override
public String filterFragment(String alias) throws MappingException { protected String filterFragment(String alias) throws MappingException {
String result = discriminatorFilterFragment( alias ); String result = discriminatorFilterFragment( alias );
if ( hasWhere() ) { if ( hasWhere() ) {
result += " and " + getSQLWhereString( alias ); result += " and " + getSQLWhereString( alias );
@ -593,7 +593,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
} }
@Override @Override
public String filterFragment(String alias, Set<String> treatAsDeclarations) { protected String filterFragment(String alias, Set<String> treatAsDeclarations) {
String result = discriminatorFilterFragment( alias, treatAsDeclarations ); String result = discriminatorFilterFragment( alias, treatAsDeclarations );
if ( hasWhere() ) { if ( hasWhere() ) {
result += " and " + getSQLWhereString( alias ); result += " and " + getSQLWhereString( alias );
@ -825,7 +825,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
return subclassTableIsLazyClosure[j]; return subclassTableIsLazyClosure[j];
} }
protected boolean isNullableTable(int j) { public boolean isNullableTable(int j) {
return isNullableTable[j]; return isNullableTable[j];
} }

View File

@ -308,22 +308,22 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
} }
@Override @Override
protected String getTableName(int j) { public String getTableName(int j) {
return tableName; return tableName;
} }
@Override @Override
protected String[] getKeyColumns(int j) { public String[] getKeyColumns(int j) {
return getIdentifierColumnNames(); return getIdentifierColumnNames();
} }
@Override @Override
protected boolean isTableCascadeDeleteEnabled(int j) { public boolean isTableCascadeDeleteEnabled(int j) {
return false; return false;
} }
@Override @Override
protected boolean isPropertyOfTable(int property, int j) { public boolean isPropertyOfTable(int property, int j) {
return true; return true;
} }
@ -335,7 +335,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
} }
@Override @Override
public String filterFragment(String name) { protected String filterFragment(String name) {
return hasWhere() return hasWhere()
? " and " + getSQLWhereString( name ) ? " and " + getSQLWhereString( name )
: ""; : "";

View File

@ -16,13 +16,13 @@ import java.util.Map;
*/ */
public class Delete { public class Delete {
private String tableName; protected String tableName;
private String versionColumnName; protected String versionColumnName;
private String where; protected String where;
protected String comment;
protected Map<String,String> primaryKeyColumns = new LinkedHashMap<>();
private Map primaryKeyColumns = new LinkedHashMap();
private String comment;
public Delete setComment(String comment) { public Delete setComment(String comment) {
this.comment = comment; this.comment = comment;
return this; return this;
@ -43,9 +43,9 @@ public class Delete {
buf.append( " where " ); buf.append( " where " );
} }
boolean conditionsAppended = false; boolean conditionsAppended = false;
Iterator iter = primaryKeyColumns.entrySet().iterator(); Iterator<Map.Entry<String,String>> iter = primaryKeyColumns.entrySet().iterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
Map.Entry e = (Map.Entry) iter.next(); Map.Entry<String,String> e = iter.next();
buf.append( e.getKey() ).append( '=' ).append( e.getValue() ); buf.append( e.getKey() ).append( '=' ).append( e.getValue() );
if ( iter.hasNext() ) { if ( iter.hasNext() ) {
buf.append( " and " ); buf.append( " and " );

View File

@ -25,8 +25,8 @@ public class InFragment {
public static final String NULL = "null"; public static final String NULL = "null";
public static final String NOT_NULL = "not null"; public static final String NOT_NULL = "not null";
private String columnName; protected String columnName;
private List<Object> values = new ArrayList<Object>(); protected List<Object> values = new ArrayList<Object>();
/** /**
* @param value an SQL literal, NULL, or NOT_NULL * @param value an SQL literal, NULL, or NOT_NULL

View File

@ -19,10 +19,13 @@ import org.hibernate.type.LiteralType;
* @author Gavin King * @author Gavin King
*/ */
public class Insert { public class Insert {
protected String tableName;
protected String comment;
protected Map<String,String> columns = new LinkedHashMap<>();
private Dialect dialect; private Dialect dialect;
private String tableName;
private String comment;
private Map columns = new LinkedHashMap();
public Insert(Dialect dialect) { public Insert(Dialect dialect) {
this.dialect = dialect; this.dialect = dialect;
@ -111,7 +114,7 @@ public class Insert {
} }
else { else {
buf.append(" ("); buf.append(" (");
Iterator iter = columns.keySet().iterator(); Iterator<String> iter = columns.keySet().iterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
buf.append( iter.next() ); buf.append( iter.next() );
if ( iter.hasNext() ) { if ( iter.hasNext() ) {

View File

@ -21,10 +21,13 @@ import org.hibernate.dialect.Dialect;
*/ */
@Deprecated @Deprecated
public class InsertSelect { public class InsertSelect {
private String tableName;
private String comment; protected String tableName;
private List columnNames = new ArrayList(); protected String comment;
private Select select;
protected List<String> columnNames = new ArrayList<>();
protected Select select;
public InsertSelect(Dialect dialect) { public InsertSelect(Dialect dialect) {
//This is no longer used. Deprecate & remove? //This is no longer used. Deprecate & remove?
@ -73,7 +76,7 @@ public class InsertSelect {
buf.append( "insert into " ).append( tableName ); buf.append( "insert into " ).append( tableName );
if ( !columnNames.isEmpty() ) { if ( !columnNames.isEmpty() ) {
buf.append( " (" ); buf.append( " (" );
Iterator itr = columnNames.iterator(); Iterator<String> itr = columnNames.iterator();
while ( itr.hasNext() ) { while ( itr.hasNext() ) {
buf.append( itr.next() ); buf.append( itr.next() );
if ( itr.hasNext() ) { if ( itr.hasNext() ) {

View File

@ -17,15 +17,17 @@ import org.hibernate.internal.util.StringHelper;
*/ */
public class Select { public class Select {
private String selectClause; protected String selectClause;
private String fromClause; protected String fromClause;
private String outerJoinsAfterFrom; protected String outerJoinsAfterFrom;
private String whereClause; protected String whereClause;
private String outerJoinsAfterWhere; protected String outerJoinsAfterWhere;
private String orderByClause; protected String orderByClause;
private String groupByClause; protected String groupByClause;
private String comment; protected String comment;
private LockOptions lockOptions = new LockOptions();
protected LockOptions lockOptions = new LockOptions();
public final Dialect dialect; public final Dialect dialect;
private int guesstimatedBufferSize = 20; private int guesstimatedBufferSize = 20;

View File

@ -31,15 +31,18 @@ public class SimpleSelect {
//private static final Alias DEFAULT_ALIAS = new Alias(10, null); //private static final Alias DEFAULT_ALIAS = new Alias(10, null);
private String tableName; protected String tableName;
private String orderBy; protected String orderBy;
private Dialect dialect; protected String comment;
private LockOptions lockOptions = new LockOptions( LockMode.READ );
private String comment; protected List<String> columns = new ArrayList<String>();
protected Map<String, String> aliases = new HashMap<String, String>();
protected List<String> whereTokens = new ArrayList<String>();
protected LockOptions lockOptions = new LockOptions( LockMode.READ );
private Dialect dialect;
private List<String> columns = new ArrayList<String>();
private Map<String, String> aliases = new HashMap<String, String>();
private List<String> whereTokens = new ArrayList<String>();
public SimpleSelect addColumns(String[] columnNames, String[] columnAliases) { public SimpleSelect addColumns(String[] columnNames, String[] columnAliases) {
for ( int i = 0; i < columnNames.length; i++ ) { for ( int i = 0; i < columnNames.length; i++ ) {

View File

@ -19,15 +19,15 @@ import org.hibernate.type.LiteralType;
*/ */
public class Update { public class Update {
private String tableName; protected String tableName;
private String versionColumnName; protected String versionColumnName;
private String where; protected String where;
private String assignments; protected String assignments;
private String comment; protected String comment;
private Map primaryKeyColumns = new LinkedHashMap(); protected Map<String,String> primaryKeyColumns = new LinkedHashMap<>();
private Map columns = new LinkedHashMap(); protected Map<String,String> columns = new LinkedHashMap<>();
private Map whereColumns = new LinkedHashMap(); protected Map<String,String> whereColumns = new LinkedHashMap<>();
private Dialect dialect; private Dialect dialect;
@ -170,9 +170,9 @@ public class Update {
} }
buf.append( "update " ).append( tableName ).append( " set " ); buf.append( "update " ).append( tableName ).append( " set " );
boolean assignmentsAppended = false; boolean assignmentsAppended = false;
Iterator iter = columns.entrySet().iterator(); Iterator<Map.Entry<String,String>> iter = columns.entrySet().iterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
Map.Entry e = (Map.Entry) iter.next(); Map.Entry<String,String> e = iter.next();
buf.append( e.getKey() ).append( '=' ).append( e.getValue() ); buf.append( e.getKey() ).append( '=' ).append( e.getValue() );
if ( iter.hasNext() ) { if ( iter.hasNext() ) {
buf.append( ", " ); buf.append( ", " );
@ -192,7 +192,7 @@ public class Update {
} }
iter = primaryKeyColumns.entrySet().iterator(); iter = primaryKeyColumns.entrySet().iterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
Map.Entry e = (Map.Entry) iter.next(); Map.Entry<String,String> e = iter.next();
buf.append( e.getKey() ).append( '=' ).append( e.getValue() ); buf.append( e.getKey() ).append( '=' ).append( e.getValue() );
if ( iter.hasNext() ) { if ( iter.hasNext() ) {
buf.append( " and " ); buf.append( " and " );
@ -208,7 +208,7 @@ public class Update {
} }
iter = whereColumns.entrySet().iterator(); iter = whereColumns.entrySet().iterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
final Map.Entry e = (Map.Entry) iter.next(); final Map.Entry<String,String> e = iter.next();
if ( conditionsAppended ) { if ( conditionsAppended ) {
buf.append( " and " ); buf.append( " and " );
} }

View File

@ -14,6 +14,9 @@ import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import org.hibernate.boot.SessionFactoryBuilder; import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.jpa.QueryHints; import org.hibernate.jpa.QueryHints;
@ -34,6 +37,9 @@ import static org.junit.Assert.assertTrue;
@TestForIssue( jiraKey = "HHH-10965" ) @TestForIssue( jiraKey = "HHH-10965" )
public class SelectDistinctHqlTest extends BaseNonConfigCoreFunctionalTestCase { public class SelectDistinctHqlTest extends BaseNonConfigCoreFunctionalTestCase {
private static final String DISTINCT_PASSES_THROUGH_TRUE_NAMED_QUERY = "distinctPassesThroughTrue";
private static final String DISTINCT_PASSES_THROUGH_FALSE_NAMED_QUERY = "distinctPassesThroughFalse";
private static final String DISTINCT_PASSES_THROUGH_NOT_SPECIFIED_NAMED_QUERY = "distinctPassesThroughNotSpecified";
private SQLStatementInterceptor sqlStatementInterceptor; private SQLStatementInterceptor sqlStatementInterceptor;
@Override @Override
@ -137,7 +143,65 @@ public class SelectDistinctHqlTest extends BaseNonConfigCoreFunctionalTestCase {
}); });
} }
@Test
@TestForIssue(jiraKey = "HHH-13780")
public void testNamedQueryDistinctPassThroughTrue() {
doInHibernate( this::sessionFactory, session -> {
sqlStatementInterceptor.getSqlQueries().clear();
List<Person> persons = session.createNamedQuery( DISTINCT_PASSES_THROUGH_TRUE_NAMED_QUERY, Person.class )
.setMaxResults( 5 )
.getResultList();
assertEquals( 1, persons.size() );
String sqlQuery = sqlStatementInterceptor.getSqlQueries().getLast();
assertTrue( sqlQuery.contains( " distinct " ) );
} );
}
@Test
@TestForIssue(jiraKey = "HHH-13780")
public void testNamedQueryDistinctPassThroughTrueWhenNotSpecified() {
doInHibernate( this::sessionFactory, session -> {
sqlStatementInterceptor.getSqlQueries().clear();
List<Person> persons =
session.createNamedQuery( DISTINCT_PASSES_THROUGH_NOT_SPECIFIED_NAMED_QUERY, Person.class )
.setMaxResults( 5 )
.getResultList();
assertEquals( 1, persons.size() );
String sqlQuery = sqlStatementInterceptor.getSqlQueries().getLast();
assertTrue( sqlQuery.contains( " distinct " ) );
} );
}
@Test
@TestForIssue(jiraKey = "HHH-13780")
public void testNamedQueryDistinctPassThroughFalse() {
doInHibernate( this::sessionFactory, session -> {
sqlStatementInterceptor.getSqlQueries().clear();
List<Person> persons =
session.createNamedQuery( DISTINCT_PASSES_THROUGH_FALSE_NAMED_QUERY, Person.class )
.setMaxResults( 5 )
.getResultList();
assertEquals( 1, persons.size() );
String sqlQuery = sqlStatementInterceptor.getSqlQueries().getLast();
assertFalse( sqlQuery.contains( " distinct " ) );
} );
}
@Entity(name = "Person") @Entity(name = "Person")
@NamedQueries({
@NamedQuery(name = DISTINCT_PASSES_THROUGH_TRUE_NAMED_QUERY,
query = "select distinct p from Person p left join fetch p.phones",
hints = {
@QueryHint(name = QueryHints.HINT_PASS_DISTINCT_THROUGH, value = "true")
}),
@NamedQuery(name = DISTINCT_PASSES_THROUGH_FALSE_NAMED_QUERY,
query = "select distinct p from Person p left join fetch p.phones",
hints = {
@QueryHint(name = QueryHints.HINT_PASS_DISTINCT_THROUGH, value = "false")
}),
@NamedQuery(name = DISTINCT_PASSES_THROUGH_NOT_SPECIFIED_NAMED_QUERY,
query = "select distinct p from Person p left join fetch p.phones")
})
public static class Person { public static class Person {
@Id @Id

View File

@ -11,6 +11,7 @@ import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.annotations.NaturalId; import org.hibernate.annotations.NaturalId;
import org.hibernate.query.Query; import org.hibernate.query.Query;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -21,10 +22,13 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -239,6 +243,16 @@ public class NaturalIdDereferenceTest extends BaseCoreFunctionalTestCase {
} ); } );
} }
@Test
@TestForIssue(jiraKey = "HHH-13752")
public void deleteWithNaturalIdBasedJoinTable() {
doInHibernate( this::sessionFactory, session -> {
Query query = session.createQuery(
"DELETE FROM Book b WHERE 1=0" );
query.executeUpdate();
} );
}
private int getSQLJoinCount(Query query) { private int getSQLJoinCount(Query query) {
String sqlQuery = getSQLQuery( query ).toLowerCase(); String sqlQuery = getSQLQuery( query ).toLowerCase();
@ -317,6 +331,14 @@ public class NaturalIdDereferenceTest extends BaseCoreFunctionalTestCase {
@Column(name = "isbn", unique = true) @Column(name = "isbn", unique = true)
private String isbn; private String isbn;
@OneToMany
@JoinTable(
name = "similar_books",
joinColumns = @JoinColumn(name = "base_isbn", referencedColumnName = "isbn"),
inverseJoinColumns = @JoinColumn(name = "ref_isbn", referencedColumnName = "isbn_ref")
)
private Set<BookRef> similarBooks;
} }
@Entity(name = "BookRef") @Entity(name = "BookRef")

View File

@ -80,6 +80,8 @@ import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
public class OsgiIntegrationTest { public class OsgiIntegrationTest {
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private static final String jbossPublicRepository = "https://repository.jboss.org/nexus/content/groups/public-jboss/";
private static final String mavenCentralRepository = "https://repo.maven.apache.org/maven2/";
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Prepare the Karaf container // Prepare the Karaf container
@ -108,10 +110,15 @@ public class OsgiIntegrationTest {
) )
) )
.useDeployFolder( false ), .useDeployFolder( false ),
editConfigurationFileExtend( editConfigurationFilePut( // Erase the defaults: Maven Central uses HTTP by default, but HTTPS is required now.
"etc/org.ops4j.pax.url.mvn.cfg", "etc/org.ops4j.pax.url.mvn.cfg",
"org.ops4j.pax.url.mvn.repositories", "org.ops4j.pax.url.mvn.repositories",
"https://repository.jboss.org/nexus/content/groups/public/" mavenCentralRepository
+ "@id=central"
+ ", "
+ jbossPublicRepository
+ "@id=jboss-public-repository"
+ "https://repository.jboss.org/nexus/content/groups/public/"
), ),
configureConsole().ignoreLocalConsole().ignoreRemoteShell(), configureConsole().ignoreLocalConsole().ignoreRemoteShell(),
when( debug ).useOptions( keepRuntimeFolder() ), when( debug ).useOptions( keepRuntimeFolder() ),