Fix readOnly value and Query#scroll()

This commit is contained in:
Andrea Boriero 2021-11-28 17:09:35 +01:00 committed by Andrea Boriero
parent 0fbfc30eaa
commit b4cfe7e54a
22 changed files with 1097 additions and 715 deletions

View File

@ -18,6 +18,7 @@ import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.LockOptions;
import org.hibernate.ScrollMode;
import org.hibernate.cache.spi.QueryKey;
@ -25,11 +26,17 @@ import org.hibernate.cache.spi.QueryResultsCache;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.graph.spi.AppliedGraph;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.query.Limit;
import org.hibernate.query.ResultListTransformer;
import org.hibernate.query.TupleTransformer;
import org.hibernate.query.internal.ScrollableResultsIterator;
import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.ScrollableResultsImplementor;
import org.hibernate.sql.exec.SqlExecLogger;
import org.hibernate.sql.exec.spi.Callback;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.JdbcSelect;
@ -58,6 +65,9 @@ import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.CacheRetrieveMode;
import jakarta.persistence.CacheStoreMode;
/**
* @author Steve Ebersole
*/
@ -104,7 +114,7 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor {
RowTransformer<R> rowTransformer) {
final SharedSessionContractImplementor session = executionContext.getSession();
session.autoFlushIfRequired( jdbcSelect.getAffectedTableNames() );
return executeQuery(
return executeQueryScroll(
jdbcSelect,
jdbcParameterBindings,
executionContext,
@ -169,6 +179,150 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor {
}
}
}
private <T, R> T executeQueryScroll(
JdbcSelect jdbcSelect,
JdbcParameterBindings jdbcParameterBindings,
ExecutionContext executionContext,
RowTransformer<R> rowTransformer,
Function<String, PreparedStatement> statementCreator,
ResultsConsumer<T, R> resultsConsumer) {
return doExecuteQuery(
jdbcSelect,
jdbcParameterBindings,
getScrollContext( executionContext, executionContext.getSession().getPersistenceContext() ),
rowTransformer,
statementCreator,
resultsConsumer
);
}
/*
When `Query#scroll()` is call the query is not executed immediately, a new ExecutionContext with the values of the `persistenceContext.isDefaultReadOnly()` and of the `queryOptions.isReadOnly()`
set at the moment of the Query#scroll() call is created in order to use it when the query will be executed.
*/
private ExecutionContext getScrollContext(ExecutionContext context, PersistenceContext persistenceContext) {
final QueryOptions queryOptions = context.getQueryOptions();
final Boolean readOnly;
if ( queryOptions.isReadOnly() == null ) {
readOnly = persistenceContext.isDefaultReadOnly();
}
else {
readOnly = queryOptions.isReadOnly();
}
final Integer timeout = queryOptions.getTimeout();
final FlushMode flushMode = queryOptions.getFlushMode();
final AppliedGraph appliedGraph = queryOptions.getAppliedGraph();
final TupleTransformer tupleTransformer = queryOptions.getTupleTransformer();
final ResultListTransformer resultListTransformer = queryOptions.getResultListTransformer();
final Boolean resultCachingEnabled = queryOptions.isResultCachingEnabled();
final CacheRetrieveMode cacheRetrieveMode = queryOptions.getCacheRetrieveMode();
final CacheStoreMode cacheStoreMode = queryOptions.getCacheStoreMode();
final String resultCacheRegionName = queryOptions.getResultCacheRegionName();
final LockOptions lockOptions = queryOptions.getLockOptions();
final String comment = queryOptions.getComment();
final List<String> databaseHints = queryOptions.getDatabaseHints();
final Integer fetchSize = queryOptions.getFetchSize();
final Limit limit = queryOptions.getLimit();
return new ExecutionContext() {
@Override
public QueryOptions getQueryOptions() {
return new QueryOptions() {
@Override
public Integer getTimeout() {
return timeout;
}
@Override
public FlushMode getFlushMode() {
return flushMode;
}
@Override
public Boolean isReadOnly() {
return readOnly;
}
@Override
public AppliedGraph getAppliedGraph() {
return appliedGraph;
}
@Override
public TupleTransformer getTupleTransformer() {
return tupleTransformer;
}
@Override
public ResultListTransformer getResultListTransformer() {
return resultListTransformer;
}
@Override
public Boolean isResultCachingEnabled() {
return resultCachingEnabled;
}
@Override
public CacheRetrieveMode getCacheRetrieveMode() {
return cacheRetrieveMode;
}
@Override
public CacheStoreMode getCacheStoreMode() {
return cacheStoreMode;
}
@Override
public String getResultCacheRegionName() {
return resultCacheRegionName;
}
@Override
public LockOptions getLockOptions() {
return lockOptions;
}
@Override
public String getComment() {
return comment;
}
@Override
public List<String> getDatabaseHints() {
return databaseHints;
}
@Override
public Integer getFetchSize() {
return fetchSize;
}
@Override
public Limit getLimit() {
return limit;
}
};
}
@Override
public QueryParameterBindings getQueryParameterBindings() {
return context.getQueryParameterBindings();
}
@Override
public Callback getCallback() {
return context.getCallback();
}
@Override
public SharedSessionContractImplementor getSession() {
return context.getSession();
}
};
}
private <T, R> T doExecuteQuery(
JdbcSelect jdbcSelect,
JdbcParameterBindings jdbcParameterBindings,

View File

@ -872,13 +872,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
private boolean isReadOnly(
RowProcessingState rowProcessingState,
SharedSessionContractImplementor persistenceContext) {
if ( persistenceContext.isDefaultReadOnly() ) {
return true;
}
final Boolean queryOption = rowProcessingState.getJdbcValuesSourceProcessingState().getQueryOptions().isReadOnly();
return queryOption == null ? false : queryOption;
final Boolean readOnly = rowProcessingState.getQueryOptions().isReadOnly();
return readOnly == null ? persistenceContext.isDefaultReadOnly() : readOnly;
}
private void preLoad(RowProcessingState rowProcessingState) {

View File

@ -4,7 +4,7 @@
* 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.readonly;
package org.hibernate.orm.test.readonly;
import org.hibernate.CacheMode;
import org.hibernate.cfg.AvailableSettings;

View File

@ -4,7 +4,7 @@
* 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.readonly;
package org.hibernate.orm.test.readonly;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

View File

@ -6,7 +6,7 @@
*/
//$Id: Course.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.readonly;
package org.hibernate.orm.test.readonly;
/**

View File

@ -10,7 +10,7 @@
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="org.hibernate.test.readonly">
package="org.hibernate.orm.test.readonly">
<class name="DataPoint"
dynamic-update="true">

View File

@ -6,7 +6,7 @@
*/
//$Id: DataPoint.java 7231 2005-06-19 22:04:00Z oneovthafew $
package org.hibernate.test.readonly;
package org.hibernate.orm.test.readonly;
import java.io.Serializable;
import java.math.BigDecimal;

View File

@ -9,7 +9,7 @@
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.readonly">
<hibernate-mapping package="org.hibernate.orm.test.readonly">
<class name="Course">
<id name="courseCode">

View File

@ -6,7 +6,7 @@
*/
//$Id: Enrolment.java 6970 2005-05-31 20:24:41Z oneovthafew $
package org.hibernate.test.readonly;
package org.hibernate.orm.test.readonly;
import java.io.Serializable;
/**

View File

@ -4,7 +4,7 @@
* 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.readonly;
package org.hibernate.orm.test.readonly;
/**

View File

@ -4,7 +4,7 @@
* 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.readonly;
package org.hibernate.orm.test.readonly;
import java.io.Serializable;
/**

View File

@ -20,11 +20,6 @@ import org.hibernate.proxy.HibernateProxy;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.test.readonly.AbstractReadOnlyTest;
import org.hibernate.test.readonly.Container;
import org.hibernate.test.readonly.DataPoint;
import org.hibernate.test.readonly.Info;
import org.hibernate.test.readonly.Owner;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -56,7 +51,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
* @author Gail Badner
*/
@DomainModel(
xmlMappings = { "org/hibernate/test/readonly/DataPoint.hbm.xml" }
xmlMappings = { "org/hibernate/orm/test/readonly/DataPoint.hbm.xml" }
)
public class ReadOnlySessionLazyNonLazyTest extends AbstractReadOnlyTest {

View File

@ -4,7 +4,7 @@
* 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.readonly;
package org.hibernate.orm.test.readonly;
import java.math.BigDecimal;
import java.util.List;
@ -34,8 +34,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
*/
@DomainModel(
xmlMappings = {
"org/hibernate/test/readonly/DataPoint.hbm.xml",
"org/hibernate/test/readonly/TextHolder.hbm.xml"
"org/hibernate/orm/test/readonly/DataPoint.hbm.xml",
"org/hibernate/orm/test/readonly/TextHolder.hbm.xml"
}
)
public class ReadOnlySessionTest extends AbstractReadOnlyTest {

View File

@ -17,9 +17,6 @@ import org.hibernate.Transaction;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.test.readonly.AbstractReadOnlyTest;
import org.hibernate.test.readonly.DataPoint;
import org.hibernate.test.readonly.TextHolder;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -34,8 +31,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
*/
@DomainModel(
xmlMappings = {
"org/hibernate/test/readonly/DataPoint.hbm.xml",
"org/hibernate/test/readonly/TextHolder.hbm.xml"
"org/hibernate/orm/test/readonly/DataPoint.hbm.xml",
"org/hibernate/orm/test/readonly/TextHolder.hbm.xml"
}
)
public class ReadOnlyTest extends AbstractReadOnlyTest {

View File

@ -9,8 +9,6 @@ package org.hibernate.orm.test.readonly;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.test.readonly.AbstractReadOnlyTest;
import org.hibernate.test.readonly.VersionedNode;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@ -23,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertSame;
* @author Gail Badner
*/
@DomainModel(
xmlMappings = "org/hibernate/test/readonly/VersionedNode.hbm.xml"
xmlMappings = "org/hibernate/orm/test/readonly/VersionedNode.hbm.xml"
)
public class ReadOnlyVersionedNodesTest extends AbstractReadOnlyTest {

View File

@ -6,7 +6,7 @@
*/
//$Id: Student.java 9116 2006-01-23 21:21:01Z steveebersole $
package org.hibernate.test.readonly;
package org.hibernate.orm.test.readonly;
import java.util.HashSet;
import java.util.Set;

View File

@ -9,7 +9,7 @@
* Created on 28-Jan-2005
*
*/
package org.hibernate.test.readonly;
package org.hibernate.orm.test.readonly;
/**

View File

@ -9,7 +9,7 @@
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.readonly">
<hibernate-mapping package="org.hibernate.orm.test.readonly">
<class name="TextHolder" >
<id name="id">

View File

@ -4,7 +4,7 @@
* 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.readonly;
package org.hibernate.orm.test.readonly;
/**

View File

@ -9,7 +9,7 @@
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.readonly">
<hibernate-mapping package="org.hibernate.orm.test.readonly">
<class name="VersionedNode" table="V_NODE">
<id name="id" column="ID" type="string">

View File

@ -7,7 +7,7 @@
//$Id: $
package org.hibernate.test.readonly;
package org.hibernate.orm.test.readonly;
import java.util.HashSet;
import java.util.Set;