Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.hibernate.action.spi.AfterTransactionCompletionProcess;
import org.hibernate.action.spi.BeforeTransactionCompletionProcess;
import org.hibernate.action.spi.Executable;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.service.spi.EventListenerRegistry;
Expand Down Expand Up @@ -101,19 +100,7 @@ public String getEntityName() {
*/
public final Serializable getId() {
if ( id instanceof DelayedPostInsertIdentifier ) {
final EntityEntry entry = session.getPersistenceContext().getEntry( instance );
if ( entry == null ) {
if ( LOG.isDebugEnabled() ) {
LOG.debugf(
"Skipping action - the persistence context does not contain any entry for the entity [%s]. This may occur if an entity is created and then deleted in the same transaction/flush.",
instance
);
}
// If an Entity is created and then deleted in the same Transaction, when Action#postDelete() calls this method the persistence context
// does not contain anymore an entry.
return null;
}
final Serializable eeId = entry.getId();
final Serializable eeId = session.getPersistenceContext().getEntry( instance ).getId();
return eeId instanceof DelayedPostInsertIdentifier ? null : eeId;
}
return id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import java.io.Serializable;
import java.util.Map;

import org.hibernate.FlushMode;
import org.hibernate.LockMode;
import org.hibernate.NonUniqueObjectException;
import org.hibernate.action.internal.AbstractEntityInsertAction;
Expand Down Expand Up @@ -39,9 +38,6 @@
import org.hibernate.type.Type;
import org.hibernate.type.TypeHelper;

import static org.hibernate.FlushMode.COMMIT;
import static org.hibernate.FlushMode.MANUAL;

/**
* A convenience base class for listeners responding to save events.
*
Expand Down Expand Up @@ -248,7 +244,8 @@ protected Serializable performSaveOrReplicate(

Serializable id = key == null ? null : key.getIdentifier();

boolean shouldDelayIdentityInserts = shouldDelayIdentityInserts( requiresImmediateIdAccess, source );
boolean inTrx = source.isTransactionInProgress();
boolean shouldDelayIdentityInserts = !inTrx && !requiresImmediateIdAccess;

// Put a placeholder in entries, so we don't recurse back and try to save() the
// same object again. QUESTION: should this be done before onSave() is called?
Expand Down Expand Up @@ -320,30 +317,6 @@ protected Serializable performSaveOrReplicate(
return id;
}

private static boolean shouldDelayIdentityInserts(boolean requiresImmediateIdAccess, EventSource source) {
return shouldDelayIdentityInserts( requiresImmediateIdAccess, isPartOfTransaction( source ), source.getHibernateFlushMode() );
}

private static boolean shouldDelayIdentityInserts(
boolean requiresImmediateIdAccess,
boolean partOfTransaction,
FlushMode flushMode) {
if ( requiresImmediateIdAccess ) {
// todo : make this configurable? as a way to support this behavior with Session#save etc
return false;
}

// otherwise we should delay the IDENTITY insertions if either:
// 1) we are not part of a transaction
// 2) we are in FlushMode MANUAL or COMMIT (not AUTO nor ALWAYS)
return !partOfTransaction || flushMode == MANUAL || flushMode == COMMIT;

}

private static boolean isPartOfTransaction(EventSource source) {
return source.isTransactionInProgress() && source.getTransactionCoordinator().isJoined();
}

private AbstractEntityInsertAction addInsertAction(
Object[] values,
Serializable id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,20 @@
package org.hibernate.id;

import org.hibernate.FlushMode;
import org.hibernate.action.internal.EntityAction;
import org.hibernate.dialect.AbstractHANADialect;
import org.hibernate.internal.CoreMessageLogger;

import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.testing.logger.LoggerInspectionRule;
import org.hibernate.testing.logger.Triggerable;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import org.jboss.logging.Logger;

import static junit.framework.TestCase.assertTrue;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;

@RequiresDialectFeature(DialectChecks.SupportsIdentityColumns.class)
@TestForIssue(jiraKey = "HHH-12464")
public class CreateDeleteTest extends BaseCoreFunctionalTestCase {

@Rule
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
Logger.getMessageLogger( CoreMessageLogger.class, EntityAction.class.getName() )
);

private Triggerable triggerable;

@Before
public void setUp() {
triggerable = logInspection.watchForLogMessages(
"Skipping action - the persistence context does not contain any entry for the entity" );
triggerable.reset();
}

@Test
@SkipForDialect(value = AbstractHANADialect.class, comment = " HANA doesn't support tables consisting of only a single auto-generated column")
public void createAndDeleteAnEntityInTheSameTransactionTest() {
Expand All @@ -54,8 +30,6 @@ public void createAndDeleteAnEntityInTheSameTransactionTest() {
session.persist( entity );
session.delete( entity );
} );

assertTrue( triggerable.wasTriggered() );
}

@Override
Expand Down