HHH-18743 make batching explicit for StatelessSession
1. ignore hibernate.jdbc.batch_size setting 2. add insertMultiple() and friends Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
dd8e186416
commit
f82c581990
|
@ -203,8 +203,8 @@ public interface SharedSessionContract extends QueryProducer, AutoCloseable, Ser
|
|||
|
||||
/**
|
||||
* Set the session-level JDBC batch size. Override the
|
||||
* {@linkplain org.hibernate.boot.spi.SessionFactoryOptions#getJdbcBatchSize() factory-level}
|
||||
* JDBC batch size controlled by the configuration property
|
||||
* {@linkplain org.hibernate.boot.spi.SessionFactoryOptions#getJdbcBatchSize
|
||||
* factory-level} JDBC batch size controlled by the configuration property
|
||||
* {@value org.hibernate.cfg.AvailableSettings#STATEMENT_BATCH_SIZE}.
|
||||
*
|
||||
* @param jdbcBatchSize the new session-level JDBC batch size
|
||||
|
|
|
@ -60,6 +60,15 @@ import java.util.List;
|
|||
* <li>when an exception is thrown by a stateless session, the current
|
||||
* transaction is not automatically marked for rollback.
|
||||
* </ul>
|
||||
* <p>
|
||||
* Since version 7, the configuration property
|
||||
* {@value org.hibernate.cfg.BatchSettings#STATEMENT_BATCH_SIZE} has no effect
|
||||
* on a stateless session. Automatic batching may be enabled by explicitly
|
||||
* {@linkplain #setJdbcBatchSize setting the batch size}. However, automatic
|
||||
* batching has the side effect of delaying execution of the batched operation,
|
||||
* thus undermining the synchronous nature of operations performed through a
|
||||
* stateless session. A preferred approach is to explicitly batch operations via
|
||||
* {@link #insertMultiple}, {@link #updateMultiple}, or {@link #deleteMultiple}.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
|
@ -85,6 +94,16 @@ public interface StatelessSession extends SharedSessionContract {
|
|||
*/
|
||||
Object insert(Object entity);
|
||||
|
||||
/**
|
||||
* Insert multiple records.
|
||||
*
|
||||
* @param entities a list of transient instances to be inserted
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
@Incubating
|
||||
void insertMultiple(List<Object> entities);
|
||||
|
||||
/**
|
||||
* Insert a record.
|
||||
* <p>
|
||||
|
@ -108,6 +127,16 @@ public interface StatelessSession extends SharedSessionContract {
|
|||
*/
|
||||
void update(Object entity);
|
||||
|
||||
/**
|
||||
* Update multiple records.
|
||||
*
|
||||
* @param entities a list of detached instances to be updated
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
@Incubating
|
||||
void updateMultiple(List<Object> entities);
|
||||
|
||||
/**
|
||||
* Update a record.
|
||||
* <p>
|
||||
|
@ -129,6 +158,16 @@ public interface StatelessSession extends SharedSessionContract {
|
|||
*/
|
||||
void delete(Object entity);
|
||||
|
||||
/**
|
||||
* Delete multiple records.
|
||||
*
|
||||
* @param entities a list of detached instances to be deleted
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
@Incubating
|
||||
void deleteMultiple(List<Object> entities);
|
||||
|
||||
/**
|
||||
* Delete a record.
|
||||
* <p>
|
||||
|
@ -164,6 +203,19 @@ public interface StatelessSession extends SharedSessionContract {
|
|||
@Incubating
|
||||
void upsert(Object entity);
|
||||
|
||||
/**
|
||||
* Perform an upsert, that is, to insert the record if it does
|
||||
* not exist, or update the record if it already exists, for
|
||||
* each given record.
|
||||
*
|
||||
* @param entities a list of detached instances and new
|
||||
* instances with assigned identifiers
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
@Incubating
|
||||
void upsertMultiple(List<Object> entities);
|
||||
|
||||
/**
|
||||
* Use a SQL {@code merge into} statement to perform an upsert.
|
||||
*
|
||||
|
|
|
@ -1402,18 +1402,19 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
return exceptionConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getJdbcBatchSize() {
|
||||
return jdbcBatchSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventManager getEventManager() {
|
||||
return fastSessionServices.getEventManager();
|
||||
public void setJdbcBatchSize(Integer jdbcBatchSize) {
|
||||
this.jdbcBatchSize = jdbcBatchSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJdbcBatchSize(Integer jdbcBatchSize) {
|
||||
this.jdbcBatchSize = jdbcBatchSize;
|
||||
public EventManager getEventManager() {
|
||||
return fastSessionServices.getEventManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -105,6 +105,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
temporaryPersistenceContext = new StatefulPersistenceContext( this );
|
||||
influencers = new LoadQueryInfluencers( getFactory() );
|
||||
setUpMultitenancy( factory, influencers );
|
||||
setJdbcBatchSize( 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -119,6 +120,20 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
return insert( null, entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertMultiple(List<Object> entities) {
|
||||
final Integer batchSize = getJdbcBatchSize();
|
||||
setJdbcBatchSize( entities.size() );
|
||||
try {
|
||||
for ( Object entity : entities ) {
|
||||
insert( null, entity );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
setJdbcBatchSize( batchSize );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object insert(String entityName, Object entity) {
|
||||
checkOpen();
|
||||
|
@ -180,6 +195,20 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
delete( null, entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMultiple(List<Object> entities) {
|
||||
final Integer batchSize = getJdbcBatchSize();
|
||||
setJdbcBatchSize( entities.size() );
|
||||
try {
|
||||
for ( Object entity : entities ) {
|
||||
delete( null, entity );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
setJdbcBatchSize( batchSize );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String entityName, Object entity) {
|
||||
checkOpen();
|
||||
|
@ -215,8 +244,17 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public void upsert(Object entity) {
|
||||
upsert( null, entity );
|
||||
public void updateMultiple(List<Object> entities) {
|
||||
final Integer batchSize = getJdbcBatchSize();
|
||||
setJdbcBatchSize( entities.size() );
|
||||
try {
|
||||
for ( Object entity : entities ) {
|
||||
update( null, entity );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
setJdbcBatchSize( batchSize );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -257,6 +295,25 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upsert(Object entity) {
|
||||
upsert( null, entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upsertMultiple(List<Object> entities) {
|
||||
final Integer batchSize = getJdbcBatchSize();
|
||||
setJdbcBatchSize( entities.size() );
|
||||
try {
|
||||
for ( Object entity : entities ) {
|
||||
upsert( null, entity );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
setJdbcBatchSize( batchSize );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upsert(String entityName, Object entity) {
|
||||
checkOpen();
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.hibernate.resource.transaction.spi.TransactionCoordinator;
|
|||
/**
|
||||
* Contract for something that controls a {@link JdbcSessionContext}.
|
||||
* <p>
|
||||
* The term "JDBC session" is taken from the SQL specification which
|
||||
* The term <em>JDBC session</em> is taken from the SQL specification which
|
||||
* calls a connection and its associated transaction context a "session".
|
||||
*
|
||||
* @apiNote The name comes from the design idea of a {@code JdbcSession}
|
||||
|
@ -28,9 +28,9 @@ public interface JdbcSessionOwner {
|
|||
JdbcConnectionAccess getJdbcConnectionAccess();
|
||||
|
||||
/**
|
||||
* Obtain the builder for TransactionCoordinator instances
|
||||
* Obtain the {@link TransactionCoordinator}.
|
||||
*
|
||||
* @return The TransactionCoordinatorBuilder
|
||||
* @return The {@code TransactionCoordinator}
|
||||
*/
|
||||
TransactionCoordinator getTransactionCoordinator();
|
||||
|
||||
|
@ -43,7 +43,7 @@ public interface JdbcSessionOwner {
|
|||
void startTransactionBoundary();
|
||||
|
||||
/**
|
||||
* A after-begin callback from the coordinator to its owner.
|
||||
* An after-begin callback from the coordinator to its owner.
|
||||
*/
|
||||
void afterTransactionBegin();
|
||||
|
||||
|
@ -63,8 +63,8 @@ public interface JdbcSessionOwner {
|
|||
void flushBeforeTransactionCompletion();
|
||||
|
||||
/**
|
||||
* Get the Session-level JDBC batch size.
|
||||
* @return Session-level JDBC batch size
|
||||
* Get the session-level JDBC batch size.
|
||||
* @return session-level JDBC batch size
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
|
|
|
@ -340,6 +340,14 @@ must be explicitly set to true.
|
|||
|
||||
The signature of the `Configurable#configure` method changed from accepting just a `ServiceRegistry` instance to the new `GeneratorCreationContext` interface, which exposes a lot more useful information when configuring the generator itself. The old signature has been deprecated for removal, so you should migrate any custom `Configurable` generator implementation to the new one.
|
||||
|
||||
[[stateless-session-jdbc-batching]]
|
||||
== JDBC batching with `StatelessSession`
|
||||
|
||||
Automatic JDBC batching has the side effect of delaying the execution of the batched operation, and this undermines the synchronous nature of operations performed through a stateless session.
|
||||
In Hibernate 7, the configuration property `hibernate.jdbc.batch_size` now has no effect on a stateless session.
|
||||
Automatic batching may be enabled by explicitly calling `setJdbcBatchSize()`.
|
||||
However, the preferred approach is to explicitly batch operations via `insertMultiple()`, `updateMultiple()`, or `deleteMultiple()`.
|
||||
|
||||
[[hbm-transform]]
|
||||
== hbm.xml Transformation
|
||||
|
||||
|
|
Loading…
Reference in New Issue