Skip to content
Merged
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 @@ -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
Expand Down
52 changes: 52 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/StatelessSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@
* <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
*/
Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1402,18 +1402,19 @@ public ExceptionConverter getExceptionConverter() {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public StatelessSessionImpl(SessionFactoryImpl factory, SessionCreationOptions o
temporaryPersistenceContext = new StatefulPersistenceContext( this );
influencers = new LoadQueryInfluencers( getFactory() );
setUpMultitenancy( factory, influencers );
setJdbcBatchSize( 0 );
}

@Override
Expand All @@ -119,6 +120,20 @@ public Object insert(Object entity) {
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();
Expand Down Expand Up @@ -180,6 +195,20 @@ public void delete(Object entity) {
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();
Expand Down Expand Up @@ -215,8 +244,17 @@ public void update(Object entity) {
}

@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
Expand Down Expand Up @@ -257,6 +295,25 @@ public void update(String entityName, Object entity) {
}
}

@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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
* 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}
Expand All @@ -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();

Expand All @@ -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();

Expand All @@ -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
*/
Expand Down
8 changes: 8 additions & 0 deletions migration-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading