HHH-10294 EntityGraph improvement: For each jpa attribute, generate also a String constant holding the attribute field name
This commit is contained in:
parent
b1775c2502
commit
b711e14a6c
|
@ -85,6 +85,7 @@ import static org.hibernate.cfg.AvailableSettings.CUSTOM_ENTITY_DIRTINESS_STRATE
|
||||||
import static org.hibernate.cfg.AvailableSettings.DEFAULT_BATCH_FETCH_SIZE;
|
import static org.hibernate.cfg.AvailableSettings.DEFAULT_BATCH_FETCH_SIZE;
|
||||||
import static org.hibernate.cfg.AvailableSettings.DEFAULT_ENTITY_MODE;
|
import static org.hibernate.cfg.AvailableSettings.DEFAULT_ENTITY_MODE;
|
||||||
import static org.hibernate.cfg.AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS;
|
import static org.hibernate.cfg.AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS;
|
||||||
|
import static org.hibernate.cfg.AvailableSettings.FAIL_ON_PAGINATION_OVER_COLLECTION_FETCH;
|
||||||
import static org.hibernate.cfg.AvailableSettings.FLUSH_BEFORE_COMPLETION;
|
import static org.hibernate.cfg.AvailableSettings.FLUSH_BEFORE_COMPLETION;
|
||||||
import static org.hibernate.cfg.AvailableSettings.GENERATE_STATISTICS;
|
import static org.hibernate.cfg.AvailableSettings.GENERATE_STATISTICS;
|
||||||
import static org.hibernate.cfg.AvailableSettings.HQL_BULK_ID_STRATEGY;
|
import static org.hibernate.cfg.AvailableSettings.HQL_BULK_ID_STRATEGY;
|
||||||
|
@ -664,6 +665,8 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
||||||
|
|
||||||
private JpaComplianceImpl jpaCompliance;
|
private JpaComplianceImpl jpaCompliance;
|
||||||
|
|
||||||
|
private boolean failOnPaginationOverCollectionFetchEnabled;
|
||||||
|
|
||||||
public SessionFactoryOptionsStateStandardImpl(StandardServiceRegistry serviceRegistry) {
|
public SessionFactoryOptionsStateStandardImpl(StandardServiceRegistry serviceRegistry) {
|
||||||
this.serviceRegistry = serviceRegistry;
|
this.serviceRegistry = serviceRegistry;
|
||||||
|
|
||||||
|
@ -886,6 +889,12 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
||||||
|
|
||||||
// added the boolean parameter in case we want to define some form of "all" as discussed
|
// added the boolean parameter in case we want to define some form of "all" as discussed
|
||||||
this.jpaCompliance = new JpaComplianceImpl( configurationSettings, false );
|
this.jpaCompliance = new JpaComplianceImpl( configurationSettings, false );
|
||||||
|
|
||||||
|
this.failOnPaginationOverCollectionFetchEnabled = ConfigurationHelper.getBoolean(
|
||||||
|
FAIL_ON_PAGINATION_OVER_COLLECTION_FETCH,
|
||||||
|
configurationSettings,
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Interceptor determineInterceptor(Map configurationSettings, StrategySelector strategySelector) {
|
private static Interceptor determineInterceptor(Map configurationSettings, StrategySelector strategySelector) {
|
||||||
|
@ -1346,6 +1355,11 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
||||||
return this.jdbcStyleParamsZeroBased;
|
return this.jdbcStyleParamsZeroBased;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFailOnPaginationOverCollectionFetchEnabled() {
|
||||||
|
return this.failOnPaginationOverCollectionFetchEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JpaCompliance getJpaCompliance() {
|
public JpaCompliance getJpaCompliance() {
|
||||||
return jpaCompliance;
|
return jpaCompliance;
|
||||||
|
@ -1709,4 +1723,9 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
||||||
public boolean jdbcStyleParamsZeroBased() {
|
public boolean jdbcStyleParamsZeroBased() {
|
||||||
return options.jdbcStyleParamsZeroBased();
|
return options.jdbcStyleParamsZeroBased();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFailOnPaginationOverCollectionFetchEnabled() {
|
||||||
|
return options.isFailOnPaginationOverCollectionFetchEnabled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,7 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions {
|
||||||
private LiteralHandlingMode criteriaLiteralHandlingMode;
|
private LiteralHandlingMode criteriaLiteralHandlingMode;
|
||||||
private boolean jdbcStyleParamsZeroBased;
|
private boolean jdbcStyleParamsZeroBased;
|
||||||
private final JpaCompliance jpaCompliance;
|
private final JpaCompliance jpaCompliance;
|
||||||
|
private final boolean failOnPaginationOverCollectionFetchEnabled;
|
||||||
|
|
||||||
public SessionFactoryOptionsImpl(SessionFactoryOptionsState state) {
|
public SessionFactoryOptionsImpl(SessionFactoryOptionsState state) {
|
||||||
this.serviceRegistry = state.getServiceRegistry();
|
this.serviceRegistry = state.getServiceRegistry();
|
||||||
|
@ -222,6 +223,8 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions {
|
||||||
this.jdbcTimeZone = state.getJdbcTimeZone();
|
this.jdbcTimeZone = state.getJdbcTimeZone();
|
||||||
|
|
||||||
this.jpaCompliance = state.getJpaCompliance();
|
this.jpaCompliance = state.getJpaCompliance();
|
||||||
|
|
||||||
|
this.failOnPaginationOverCollectionFetchEnabled = state.isFailOnPaginationOverCollectionFetchEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -577,4 +580,9 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions {
|
||||||
public JpaCompliance getJpaCompliance() {
|
public JpaCompliance getJpaCompliance() {
|
||||||
return jpaCompliance;
|
return jpaCompliance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFailOnPaginationOverCollectionFetchEnabled() {
|
||||||
|
return failOnPaginationOverCollectionFetchEnabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,4 +208,6 @@ public interface SessionFactoryOptionsState {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean jdbcStyleParamsZeroBased();
|
boolean jdbcStyleParamsZeroBased();
|
||||||
|
|
||||||
|
boolean isFailOnPaginationOverCollectionFetchEnabled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,4 +406,9 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
|
||||||
public JpaCompliance getJpaCompliance() {
|
public JpaCompliance getJpaCompliance() {
|
||||||
return delegate.getJpaCompliance();
|
return delegate.getJpaCompliance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFailOnPaginationOverCollectionFetchEnabled() {
|
||||||
|
return delegate.isFailOnPaginationOverCollectionFetchEnabled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,4 +253,6 @@ public interface SessionFactoryOptions {
|
||||||
boolean jdbcStyleParamsZeroBased();
|
boolean jdbcStyleParamsZeroBased();
|
||||||
|
|
||||||
JpaCompliance getJpaCompliance();
|
JpaCompliance getJpaCompliance();
|
||||||
|
|
||||||
|
boolean isFailOnPaginationOverCollectionFetchEnabled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1151,7 +1151,7 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
||||||
* <li>{@link org.hibernate.engine.query.spi.FilterQueryPlan}</li>
|
* <li>{@link org.hibernate.engine.query.spi.FilterQueryPlan}</li>
|
||||||
* <li>{@link org.hibernate.engine.query.spi.NativeSQLQueryPlan}</li>
|
* <li>{@link org.hibernate.engine.query.spi.NativeSQLQueryPlan}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* maintained by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 2048.
|
* maintained by {@link org.hibernate.engine.query.spi.QueryPlanCache}. Default is 2048.
|
||||||
*/
|
*/
|
||||||
String QUERY_PLAN_CACHE_MAX_SIZE = "hibernate.query.plan_cache_max_size";
|
String QUERY_PLAN_CACHE_MAX_SIZE = "hibernate.query.plan_cache_max_size";
|
||||||
|
@ -1531,14 +1531,14 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
||||||
* {@code LEGACY} is the default value.
|
* {@code LEGACY} is the default value.
|
||||||
*/
|
*/
|
||||||
String BATCH_FETCH_STYLE = "hibernate.batch_fetch_style";
|
String BATCH_FETCH_STYLE = "hibernate.batch_fetch_style";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A transaction can be rolled back by another thread ("tracking by thread")
|
* A transaction can be rolled back by another thread ("tracking by thread")
|
||||||
* -- not the original application. Examples of this include a JTA
|
* -- not the original application. Examples of this include a JTA
|
||||||
* transaction timeout handled by a background reaper thread. The ability
|
* transaction timeout handled by a background reaper thread. The ability
|
||||||
* to handle this situation requires checking the Thread ID every time
|
* to handle this situation requires checking the Thread ID every time
|
||||||
* Session is called. This can certainly have performance considerations.
|
* Session is called. This can certainly have performance considerations.
|
||||||
*
|
*
|
||||||
* Default is <code>true</code> (enabled).
|
* Default is <code>true</code> (enabled).
|
||||||
*/
|
*/
|
||||||
String JTA_TRACK_BY_THREAD = "hibernate.jta.track_by_thread";
|
String JTA_TRACK_BY_THREAD = "hibernate.jta.track_by_thread";
|
||||||
|
@ -1568,7 +1568,7 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
||||||
* SchemaUpdate needs to create these constraints, but DB's
|
* SchemaUpdate needs to create these constraints, but DB's
|
||||||
* support for finding existing constraints is extremely inconsistent. Further,
|
* support for finding existing constraints is extremely inconsistent. Further,
|
||||||
* non-explicitly-named unique constraints use randomly generated characters.
|
* non-explicitly-named unique constraints use randomly generated characters.
|
||||||
*
|
*
|
||||||
* Therefore, select from these strategies.
|
* Therefore, select from these strategies.
|
||||||
* {@link org.hibernate.tool.hbm2ddl.UniqueConstraintSchemaUpdateStrategy#DROP_RECREATE_QUIETLY} (DEFAULT):
|
* {@link org.hibernate.tool.hbm2ddl.UniqueConstraintSchemaUpdateStrategy#DROP_RECREATE_QUIETLY} (DEFAULT):
|
||||||
* Attempt to drop, then (re-)create each unique constraint.
|
* Attempt to drop, then (re-)create each unique constraint.
|
||||||
|
@ -1810,4 +1810,10 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
String TABLE_GENERATOR_STORE_LAST_USED = "hibernate.id.generator.stored_last_used";
|
String TABLE_GENERATOR_STORE_LAST_USED = "hibernate.id.generator.stored_last_used";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raises an exception when in-memory pagination over collection fetch is about to be performed.
|
||||||
|
* Disabled by default. Set to true to enable.
|
||||||
|
*/
|
||||||
|
String FAIL_ON_PAGINATION_OVER_COLLECTION_FETCH = "hibernate.query.fail_on_pagination_over_collection_fetch";
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.IdentitySet;
|
import org.hibernate.internal.util.collections.IdentitySet;
|
||||||
import org.hibernate.loader.hql.QueryLoader;
|
import org.hibernate.loader.hql.QueryLoader;
|
||||||
import org.hibernate.param.CollectionFilterKeyParameterSpecification;
|
|
||||||
import org.hibernate.param.ParameterSpecification;
|
import org.hibernate.param.ParameterSpecification;
|
||||||
import org.hibernate.persister.entity.Queryable;
|
import org.hibernate.persister.entity.Queryable;
|
||||||
import org.hibernate.query.spi.ScrollableResultsImplementor;
|
import org.hibernate.query.spi.ScrollableResultsImplementor;
|
||||||
|
@ -377,7 +376,15 @@ public class QueryTranslatorImpl implements FilterTranslator {
|
||||||
|
|
||||||
QueryParameters queryParametersToUse;
|
QueryParameters queryParametersToUse;
|
||||||
if ( hasLimit && containsCollectionFetches() ) {
|
if ( hasLimit && containsCollectionFetches() ) {
|
||||||
LOG.firstOrMaxResultsSpecifiedWithCollectionFetch();
|
boolean fail = session.getFactory().getSessionFactoryOptions().isFailOnPaginationOverCollectionFetchEnabled();
|
||||||
|
if (fail) {
|
||||||
|
throw new HibernateException("firstResult/maxResults specified with collection fetch. " +
|
||||||
|
"In memory pagination was about to be applied. " +
|
||||||
|
"Failing because 'Fail on pagination over collection fetch' is enabled.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.firstOrMaxResultsSpecifiedWithCollectionFetch();
|
||||||
|
}
|
||||||
RowSelection selection = new RowSelection();
|
RowSelection selection = new RowSelection();
|
||||||
selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
|
selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
|
||||||
selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
|
selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* 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.pagination.hhh9965;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created on 17/12/17.
|
||||||
|
*
|
||||||
|
* @author Reda.Housni-Alaoui
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-9965")
|
||||||
|
public class HHH9965Test extends BaseCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHHH9965() {
|
||||||
|
Session session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
|
||||||
|
String hql = "SELECT s FROM Shop s join fetch s.products";
|
||||||
|
|
||||||
|
try{
|
||||||
|
session.createQuery(hql)
|
||||||
|
.setMaxResults(3)
|
||||||
|
.list();
|
||||||
|
fail("Pagination over collection fetch failure was expected");
|
||||||
|
} catch (Exception e){
|
||||||
|
log.info(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(Configuration cfg) {
|
||||||
|
super.configure(cfg);
|
||||||
|
cfg.setProperty( Environment.FAIL_ON_PAGINATION_OVER_COLLECTION_FETCH, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[]{
|
||||||
|
Shop.class,
|
||||||
|
Product.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.pagination.hhh9965;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created on 17/12/17.
|
||||||
|
*
|
||||||
|
* @author Reda.Housni-Alaoui
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class Product {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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.pagination.hhh9965;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created on 17/12/17.
|
||||||
|
*
|
||||||
|
* @author Reda.Housni-Alaoui
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class Shop {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@OneToMany(fetch = FetchType.LAZY)
|
||||||
|
private List<Product> products;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Product> getProducts() {
|
||||||
|
return products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProducts(List<Product> products) {
|
||||||
|
this.products = products;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue