HHH-13861 Expose the doWork() and doReturningWork() APIs on StatelessSession as well
This commit is contained in:
parent
6b1ef47a2d
commit
2f2d30e4e5
|
@ -18,8 +18,6 @@ import javax.persistence.criteria.CriteriaQuery;
|
||||||
import javax.persistence.criteria.CriteriaUpdate;
|
import javax.persistence.criteria.CriteriaUpdate;
|
||||||
|
|
||||||
import org.hibernate.graph.RootGraph;
|
import org.hibernate.graph.RootGraph;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
|
||||||
import org.hibernate.jdbc.Work;
|
|
||||||
import org.hibernate.jpa.HibernateEntityManager;
|
import org.hibernate.jpa.HibernateEntityManager;
|
||||||
import org.hibernate.query.NativeQuery;
|
import org.hibernate.query.NativeQuery;
|
||||||
import org.hibernate.stat.SessionStatistics;
|
import org.hibernate.stat.SessionStatistics;
|
||||||
|
@ -960,27 +958,6 @@ public interface Session extends SharedSessionContract, EntityManager, Hibernate
|
||||||
*/
|
*/
|
||||||
void setReadOnly(Object entityOrProxy, boolean readOnly);
|
void setReadOnly(Object entityOrProxy, boolean readOnly);
|
||||||
|
|
||||||
/**
|
|
||||||
* Controller for allowing users to perform JDBC related work using the Connection managed by this Session.
|
|
||||||
*
|
|
||||||
* @param work The work to be performed.
|
|
||||||
* @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
|
|
||||||
*/
|
|
||||||
void doWork(Work work) throws HibernateException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controller for allowing users to perform JDBC related work using the Connection managed by this Session. After
|
|
||||||
* execution returns the result of the {@link ReturningWork#execute} call.
|
|
||||||
*
|
|
||||||
* @param work The work to be performed.
|
|
||||||
* @param <T> The type of the result returned from the work
|
|
||||||
*
|
|
||||||
* @return the result from calling {@link ReturningWork#execute}.
|
|
||||||
*
|
|
||||||
* @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
|
|
||||||
*/
|
|
||||||
<T> T doReturningWork(ReturningWork<T> work) throws HibernateException;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
<T> RootGraph<T> createEntityGraph(Class<T> rootType);
|
<T> RootGraph<T> createEntityGraph(Class<T> rootType);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.hibernate.jdbc.ReturningWork;
|
||||||
|
import org.hibernate.jdbc.Work;
|
||||||
import org.hibernate.procedure.ProcedureCall;
|
import org.hibernate.procedure.ProcedureCall;
|
||||||
import org.hibernate.query.QueryProducer;
|
import org.hibernate.query.QueryProducer;
|
||||||
|
|
||||||
|
@ -190,4 +192,30 @@ public interface SharedSessionContract extends QueryProducer, Serializable {
|
||||||
* @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcBatchSize
|
* @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcBatchSize
|
||||||
*/
|
*/
|
||||||
void setJdbcBatchSize(Integer jdbcBatchSize);
|
void setJdbcBatchSize(Integer jdbcBatchSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for allowing users to perform JDBC related work using the Connection managed by this Session.
|
||||||
|
*
|
||||||
|
* @param work The work to be performed.
|
||||||
|
* @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
|
||||||
|
*/
|
||||||
|
default void doWork(Work work) throws HibernateException {
|
||||||
|
throw new UnsupportedOperationException( "The doWork method has not been implemented in this implementation of org.hibernate.engine.spi.SharedSessionContractImplemento" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for allowing users to perform JDBC related work using the Connection managed by this Session. After
|
||||||
|
* execution returns the result of the {@link ReturningWork#execute} call.
|
||||||
|
*
|
||||||
|
* @param work The work to be performed.
|
||||||
|
* @param <T> The type of the result returned from the work
|
||||||
|
*
|
||||||
|
* @return the result from calling {@link ReturningWork#execute}.
|
||||||
|
*
|
||||||
|
* @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
|
||||||
|
*/
|
||||||
|
default <T> T doReturningWork(ReturningWork<T> work) throws HibernateException {
|
||||||
|
throw new UnsupportedOperationException( "The doReturningWork method has not been implemented in this implementation of org.hibernate.engine.spi.SharedSessionContractImplemento" );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,9 @@ 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.jdbc.ReturningWork;
|
||||||
|
import org.hibernate.jdbc.Work;
|
||||||
|
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
import org.hibernate.jpa.QueryHints;
|
import org.hibernate.jpa.QueryHints;
|
||||||
import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
|
import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
|
||||||
import org.hibernate.jpa.spi.CriteriaQueryTupleTransformer;
|
import org.hibernate.jpa.spi.CriteriaQueryTupleTransformer;
|
||||||
|
@ -1059,6 +1062,28 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
||||||
return getNativeQueryImplementor( queryString, true );
|
return getNativeQueryImplementor( queryString, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doWork(final Work work) throws HibernateException {
|
||||||
|
WorkExecutorVisitable<Void> realWork = (workExecutor, connection) -> {
|
||||||
|
workExecutor.executeWork( work, connection );
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
doWork( realWork );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T doReturningWork(final ReturningWork<T> work) throws HibernateException {
|
||||||
|
WorkExecutorVisitable<T> realWork = (workExecutor, connection) -> workExecutor.executeReturningWork(
|
||||||
|
work,
|
||||||
|
connection
|
||||||
|
);
|
||||||
|
return doWork( realWork );
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T doWork(WorkExecutorVisitable<T> work) throws HibernateException {
|
||||||
|
return getJdbcCoordinator().coordinateWork( work );
|
||||||
|
}
|
||||||
|
|
||||||
protected NativeQueryImplementor getNativeQueryImplementor(
|
protected NativeQueryImplementor getNativeQueryImplementor(
|
||||||
String queryString,
|
String queryString,
|
||||||
boolean isOrdinalParameterZeroBased) {
|
boolean isOrdinalParameterZeroBased) {
|
||||||
|
|
|
@ -135,10 +135,6 @@ import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
import org.hibernate.hql.spi.QueryTranslator;
|
import org.hibernate.hql.spi.QueryTranslator;
|
||||||
import org.hibernate.internal.CriteriaImpl.CriterionEntry;
|
import org.hibernate.internal.CriteriaImpl.CriterionEntry;
|
||||||
import org.hibernate.internal.log.DeprecationLogger;
|
import org.hibernate.internal.log.DeprecationLogger;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
|
||||||
import org.hibernate.jdbc.Work;
|
|
||||||
import org.hibernate.jdbc.WorkExecutor;
|
|
||||||
import org.hibernate.jdbc.WorkExecutorVisitable;
|
|
||||||
import org.hibernate.jpa.AvailableSettings;
|
import org.hibernate.jpa.AvailableSettings;
|
||||||
import org.hibernate.jpa.QueryHints;
|
import org.hibernate.jpa.QueryHints;
|
||||||
import org.hibernate.jpa.internal.util.CacheModeHelper;
|
import org.hibernate.jpa.internal.util.CacheModeHelper;
|
||||||
|
@ -2296,33 +2292,6 @@ public class SessionImpl
|
||||||
persistenceContext.setReadOnly( entity, readOnly );
|
persistenceContext.setReadOnly( entity, readOnly );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doWork(final Work work) throws HibernateException {
|
|
||||||
WorkExecutorVisitable<Void> realWork = new WorkExecutorVisitable<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void accept(WorkExecutor<Void> workExecutor, Connection connection) throws SQLException {
|
|
||||||
workExecutor.executeWork( work, connection );
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
doWork( realWork );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T doReturningWork(final ReturningWork<T> work) throws HibernateException {
|
|
||||||
WorkExecutorVisitable<T> realWork = new WorkExecutorVisitable<T>() {
|
|
||||||
@Override
|
|
||||||
public T accept(WorkExecutor<T> workExecutor, Connection connection) throws SQLException {
|
|
||||||
return workExecutor.executeReturningWork( work, connection );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return doWork( realWork );
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> T doWork(WorkExecutorVisitable<T> work) throws HibernateException {
|
|
||||||
return getJdbcCoordinator().coordinateWork( work );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterScrollOperation() {
|
public void afterScrollOperation() {
|
||||||
// nothing to do in a stateful session
|
// nothing to do in a stateful session
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* 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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.test.stateless;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.StatelessSession;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
@RequiresDialect(H2Dialect.class)
|
||||||
|
public class StatelessDoWorkTest extends BaseCoreFunctionalTestCase {
|
||||||
|
public static final String EXPECTED_ENTITY_NAME = "test";
|
||||||
|
public static final Integer PERSISTED_TEST_ENTITY_ID = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] { TestEntity.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
TestEntity entity = new TestEntity( PERSISTED_TEST_ENTITY_ID, EXPECTED_ENTITY_NAME );
|
||||||
|
session.save( entity );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
session.createQuery( "delete from TestEntity" ).executeUpdate();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoReturningWork() {
|
||||||
|
String retrievedEntityName;
|
||||||
|
try (StatelessSession statelessSession = sessionFactory().openStatelessSession()) {
|
||||||
|
retrievedEntityName = statelessSession.doReturningWork(
|
||||||
|
(connection) -> {
|
||||||
|
try (PreparedStatement preparedStatement = connection.prepareStatement(
|
||||||
|
"SELECT NAME FROM TEST_ENTITY WHERE ID = ?" )) {
|
||||||
|
preparedStatement.setInt( 1, PERSISTED_TEST_ENTITY_ID );
|
||||||
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
|
String name = null;
|
||||||
|
if ( resultSet.next() ) {
|
||||||
|
name = resultSet.getString( 1 );
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat( retrievedEntityName, is( EXPECTED_ENTITY_NAME ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoWork() {
|
||||||
|
try (StatelessSession statelessSession = sessionFactory().openStatelessSession()) {
|
||||||
|
statelessSession.doWork(
|
||||||
|
(connection) -> {
|
||||||
|
try (PreparedStatement preparedStatement = connection.prepareStatement(
|
||||||
|
"DELETE FROM TEST_ENTITY " )) {
|
||||||
|
preparedStatement.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThatAllTestEntitiesHaveBeenDeleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertThatAllTestEntitiesHaveBeenDeleted() {
|
||||||
|
inTransaction( session -> {
|
||||||
|
List results = session.createQuery( "from TestEntity" ).list();
|
||||||
|
assertThat( results.size(), is( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "TestEntity")
|
||||||
|
@Table(name = "TEST_ENTITY")
|
||||||
|
public static class TestEntity {
|
||||||
|
@Id
|
||||||
|
@Column(name = "ID")
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@Column(name = "NAME")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public TestEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestEntity(Integer id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue