MutationExecutor Add call to autoFlushIfRequired

This commit is contained in:
Andrea Boriero 2020-08-27 14:34:35 +01:00 committed by Andrea Boriero
parent fc6f515407
commit 72b548b912
14 changed files with 67 additions and 33 deletions

View File

@ -371,6 +371,11 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
return delegate.getPersistenceContextInternal();
}
@Override
public boolean autoFlushIfRequired(Set<String> querySpaces) throws HibernateException {
return delegate.autoFlushIfRequired( querySpaces );
}
@Override
public SessionEventListenerManager getEventListenerManager() {
return delegate.getEventListenerManager();

View File

@ -9,6 +9,7 @@ package org.hibernate.engine.spi;
import java.io.Serializable;
import java.sql.Connection;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import javax.persistence.FlushModeType;
import javax.persistence.TransactionRequiredException;
@ -466,6 +467,16 @@ public interface SharedSessionContractImplementor
*/
PersistenceContext getPersistenceContextInternal();
/**
* detect in-memory changes, determine if the changes are to tables
* named in the query and, if so, complete execution the flush
*
* @param querySpaces the tables named in the query.
*
* @return true if flush is required, false otherwise.
*/
boolean autoFlushIfRequired(Set<String> querySpaces) throws HibernateException;
default boolean isEnforcingFetchGraph() {
return false;
}

View File

@ -1288,11 +1288,8 @@ public class SessionImpl
delayedAfterCompletion();
}
/**
* detect in-memory changes, determine if the changes are to tables
* named in the query and, if so, complete execution the flush
*/
protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
@Override
public boolean autoFlushIfRequired(Set<String> querySpaces) throws HibernateException {
checkOpen();
if ( !isTransactionInProgress() ) {
// do not auto-flush while outside a transaction

View File

@ -8,6 +8,7 @@ package org.hibernate.internal;
import java.io.Serializable;
import java.sql.Connection;
import java.util.Set;
import javax.transaction.SystemException;
import org.hibernate.CacheMode;
@ -565,6 +566,11 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
return temporaryPersistenceContext;
}
@Override
public boolean autoFlushIfRequired(Set<String> querySpaces) throws HibernateException {
return false;
}
// @Override
// public int executeNativeUpdate(
// NativeSQLQuerySpecification nativeSQLQuerySpecification,

View File

@ -12,6 +12,7 @@ import java.util.Map;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.MappingModelHelper;
@ -62,7 +63,8 @@ public class SimpleDeleteQueryPlan implements NonSelectQueryPlan {
@Override
public int executeUpdate(ExecutionContext executionContext) {
final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
final SharedSessionContractImplementor session = executionContext.getSession();
final SessionFactoryImplementor factory = session.getFactory();
final JdbcServices jdbcServices = factory.getJdbcServices();
if ( jdbcDelete == null ) {
@ -98,7 +100,7 @@ public class SimpleDeleteQueryPlan implements NonSelectQueryPlan {
jdbcParamsXref,
factory.getDomainModel(),
sqmInterpretation.getFromClauseAccess()::findTableGroup,
executionContext.getSession()
session
);
jdbcDelete.bindFilterJdbcParameters( jdbcParameterBindings );
@ -151,7 +153,7 @@ public class SimpleDeleteQueryPlan implements NonSelectQueryPlan {
return jdbcServices.getJdbcMutationExecutor().execute(
jdbcDelete,
jdbcParameterBindings,
sql -> executionContext.getSession()
sql -> session
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( sql ),

View File

@ -9,6 +9,7 @@ package org.hibernate.query.sqm.internal;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.spi.NonSelectQueryPlan;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryParameterImplementor;
@ -48,7 +49,8 @@ public class SimpleInsertQueryPlan implements NonSelectQueryPlan {
@Override
public int executeUpdate(ExecutionContext executionContext) {
final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
final SharedSessionContractImplementor session = executionContext.getSession();
final SessionFactoryImplementor factory = session.getFactory();
final JdbcServices jdbcServices = factory.getJdbcServices();
if ( jdbcInsert == null ) {
@ -87,13 +89,15 @@ public class SimpleInsertQueryPlan implements NonSelectQueryPlan {
jdbcParamsXref,
factory.getDomainModel(),
tableGroupAccess::findTableGroup,
executionContext.getSession()
session
);
jdbcInsert.bindFilterJdbcParameters( jdbcParameterBindings );
return jdbcServices.getJdbcMutationExecutor().execute(
jdbcInsert,
jdbcParameterBindings,
sql -> executionContext.getSession()
sql -> session
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( sql ),

View File

@ -12,6 +12,7 @@ import java.util.Map;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.spi.NonSelectQueryPlan;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryParameterImplementor;
@ -48,7 +49,8 @@ public class SimpleUpdateQueryPlan implements NonSelectQueryPlan {
@Override
public int executeUpdate(ExecutionContext executionContext) {
final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
final SharedSessionContractImplementor session = executionContext.getSession();
final SessionFactoryImplementor factory = session.getFactory();
final JdbcServices jdbcServices = factory.getJdbcServices();
if ( jdbcUpdate == null ) {
@ -87,14 +89,14 @@ public class SimpleUpdateQueryPlan implements NonSelectQueryPlan {
jdbcParamsXref,
factory.getDomainModel(),
tableGroupAccess::findTableGroup,
executionContext.getSession()
session
);
jdbcUpdate.bindFilterJdbcParameters( jdbcParameterBindings );
return jdbcServices.getJdbcMutationExecutor().execute(
jdbcUpdate,
jdbcParameterBindings,
sql -> executionContext.getSession()
sql -> session
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( sql ),

View File

@ -169,7 +169,6 @@ public final class ExecuteWithIdTableHelper {
entityDescriptor,
LockMode.NONE,
idTableReference,
Collections.emptyList(),
null,
executionContext.getSession().getFactory()
);

View File

@ -45,7 +45,6 @@ public final class ExecuteWithoutIdTableHelper {
rootEntityPersister,
LockMode.PESSIMISTIC_WRITE,
rootTableReference,
Collections.emptyList(),
null,
sessionFactory
);

View File

@ -30,7 +30,8 @@ public class StandardSqlAstDeleteTranslator extends AbstractSqlAstTranslator imp
@Override
public JdbcDelete translate(DeleteStatement sqlAst) {
appendSql( "delete from " );
appendSql( sqlAst.getTargetTable().getTableExpression() );
renderTableReference( sqlAst.getTargetTable() );
if ( sqlAst.getRestriction() != null ) {
appendSql( " where " );

View File

@ -83,7 +83,6 @@ public class CteTable {
null,
LockMode.NONE,
tableValueConstructorReference,
Collections.emptyList(),
null,
sessionFactory
);

View File

@ -33,12 +33,11 @@ public class StandardTableGroup extends AbstractTableGroup {
TableGroupProducer tableGroupProducer,
LockMode lockMode,
TableReference primaryTableReference,
List<TableReferenceJoin> tableJoins,
SqlAliasBase sqlAliasBase,
SessionFactoryImplementor sessionFactory) {
super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory );
this.primaryTableReference = primaryTableReference;
this.tableJoins = tableJoins;
this.tableJoins = Collections.emptyList();
this.tableReferenceJoinCreator = null;
this.tableReferenceJoinNameChecker = s -> {
for ( int i = 0; i < tableJoins.size(); i++ ) {

View File

@ -12,6 +12,7 @@ import java.util.function.BiConsumer;
import java.util.function.Function;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcMutation;
@ -35,11 +36,14 @@ public class StandardJdbcMutationExecutor implements JdbcMutationExecutor {
Function<String, PreparedStatement> statementCreator,
BiConsumer<Integer, PreparedStatement> expectationCheck,
ExecutionContext executionContext) {
final LogicalConnectionImplementor logicalConnection = executionContext.getSession()
final SharedSessionContractImplementor session = executionContext.getSession();
session.autoFlushIfRequired( jdbcMutation.getAffectedTableNames() );
final LogicalConnectionImplementor logicalConnection = session
.getJdbcCoordinator()
.getLogicalConnection();
final JdbcServices jdbcServices = executionContext.getSession().getJdbcServices();
final JdbcServices jdbcServices = session.getJdbcServices();
final String sql = jdbcMutation.getSql();
try {
@ -63,14 +67,14 @@ public class StandardJdbcMutationExecutor implements JdbcMutationExecutor {
);
}
executionContext.getSession().getEventListenerManager().jdbcExecuteStatementStart();
session.getEventListenerManager().jdbcExecuteStatementStart();
try {
int rows = preparedStatement.executeUpdate();
expectationCheck.accept( rows, preparedStatement );
return rows;
}
finally {
executionContext.getSession().getEventListenerManager().jdbcExecuteStatementEnd();
session.getEventListenerManager().jdbcExecuteStatementEnd();
}
}
finally {

View File

@ -187,6 +187,7 @@ public class PersistentMapTest {
List<User> list = q.list();
assertEquals( 1, list.size() );
session.delete( list.get( 0 ) );
}
);
}
@ -209,11 +210,11 @@ public class PersistentMapTest {
session.beginTransaction();
user = session.get( User.class, 1 );
user = session.get( User.class, user.id );
user.userDatas.clear();
session.update( user );
Query q = session.createQuery( "DELETE FROM " + UserData.class.getName() + " d WHERE d.user = :user" );
Query<UserData> q = session.createQuery( "DELETE FROM " + UserData.class.getName() + " d WHERE d.user = :user" );
q.setParameter( "user", user );
q.executeUpdate();
@ -361,30 +362,31 @@ select
@Test
@TestForIssue(jiraKey = "HHH-11038")
public void testMapKeyColumnNonInsertableNonUpdatableUnidirOneToMany(SessionFactoryScope scope) {
User user = new User();
scope.inTransaction(
Integer userId = scope.fromTransaction(
session -> {
User user = new User();
Detail detail = new Detail();
detail.description = "desc";
detail.detailType = "trivial";
user.details.put( detail.detailType, detail );
session.persist( user );
return user.getId();
}
);
scope.inTransaction(
session -> {
User u = session.get( User.class, user.id );
u.details.clear();
User user = session.get( User.class, userId);
user.details.clear();
}
);
scope.inTransaction(
session -> {
User u = session.get( User.class, user.id );
session.delete( u );
User user = session.get( User.class, userId );
session.delete( user );
session.createQuery( "delete from " + User.class.getName() ).executeUpdate();
}
);
}
@ -408,6 +410,10 @@ select
@MapKeyColumn(name = "detailType", insertable = false, updatable = false)
@JoinColumn
private Map<String, Detail> details = new HashMap<>();
public Integer getId() {
return id;
}
}
@Entity