Merge remote-tracking branch 'upstream/master' into wip/6.0_merge_22
This commit is contained in:
commit
fd6866f029
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ),
|
||||||
|
|
|
@ -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 ) ) {
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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 )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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...
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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} );
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
||||||
: "";
|
: "";
|
||||||
|
|
|
@ -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 " );
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() ) {
|
||||||
|
|
|
@ -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() ) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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++ ) {
|
||||||
|
|
|
@ -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 " );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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() ),
|
||||||
|
|
Loading…
Reference in New Issue