Check if auto flush is required for hql queries

This commit is contained in:
Andrea Boriero 2020-12-08 09:47:40 +01:00
parent f54105cc51
commit 9a6465a72f
15 changed files with 178 additions and 175 deletions

View File

@ -159,12 +159,16 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
sqmInterpretation.getTableGroupAccess()::findTableGroup,
session
);
sqmInterpretation.getJdbcSelect().bindFilterJdbcParameters( jdbcParameterBindings );
final JdbcSelect jdbcSelect = sqmInterpretation.getJdbcSelect();
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
session.autoFlushIfRequired( jdbcSelect.getAffectedTableNames() );
try {
session.autoFlushIfRequired( sqmInterpretation.getJdbcSelect().getAffectedTableNames() );
return session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
sqmInterpretation.getJdbcSelect(),
jdbcSelect,
jdbcParameterBindings,
executionContext,
rowTransformer,

View File

@ -720,20 +720,23 @@ public abstract class BaseSqmToSqlAstConverter
NavigablePath elementPath;
if ( parentNavigablePath == null ) {
elementPath = sqmJoinNavigablePath.append( CollectionPart.Nature.ELEMENT.getName() );
pluralPersisterElementNavigablePathByFullPath.put( sqmJoin.getNavigablePath().getFullPath(), elementPath );
elementPath = sqmJoinNavigablePath;
pluralPersisterElementNavigablePathByFullPath.put(
sqmJoin.getNavigablePath().getFullPath(),
elementPath
);
}
else {
final NavigablePath elementNavigablePath = pluralPersisterElementNavigablePathByFullPath.get( parentNavigablePath.getFullPath() );
final NavigablePath elementNavigablePath = pluralPersisterElementNavigablePathByFullPath.get(
parentNavigablePath.getFullPath() );
if ( elementNavigablePath == null ) {
elementPath = sqmJoinNavigablePath.append( CollectionPart.Nature.ELEMENT.getName() );
pluralPersisterElementNavigablePathByFullPath.put( sqmJoin.getNavigablePath().getFullPath(), elementPath );
elementPath = sqmJoinNavigablePath;
}
else {
elementPath = elementNavigablePath.append( pluralAttributeMapping.getPartName() );
pluralPersisterElementNavigablePathByFullPath.put( sqmJoin.getNavigablePath().getFullPath(), elementPath.append( CollectionPart.Nature.ELEMENT.getName() ) );
}
}
pluralPersisterElementNavigablePathByFullPath.put( sqmJoin.getNavigablePath().getFullPath(), elementPath.append( CollectionPart.Nature.ELEMENT.getName() ) );
joinedTableGroupJoin = pluralAttributeMapping.createTableGroupJoin(
elementPath,
@ -782,46 +785,38 @@ public abstract class BaseSqmToSqlAstConverter
fromClauseIndex.register( sqmJoin, joinedTableGroup );
}
else {
if ( lhsTableGroup.getModelPart() instanceof PluralAttributeMapping ) {
fromClauseIndex.register( sqmJoin, lhsTableGroup );
final ModelPart joinedPart = lhsTableGroup.getModelPart().findSubPart(
pathSource.getPathName(),
SqmMappingModelHelper.resolveExplicitTreatTarget( sqmJoin, this )
);
joinedTableGroupJoin = null;
joinedTableGroup = lhsTableGroup;
if ( !TableGroupJoinProducer.class.isInstance( joinedPart ) ) {
throw new HibernateException( "Expecting joined model part to implement TableGroupJoinProducer - " + joinedPart );
}
final NavigablePath joinedPath;
final String explicitAlias = sqmJoin.getExplicitAlias();
if ( explicitAlias == null ) {
joinedPath = sqmJoinNavigablePath;
}
else {
final ModelPart joinedPart = lhsTableGroup.getModelPart().findSubPart(
pathSource.getPathName(),
SqmMappingModelHelper.resolveExplicitTreatTarget( sqmJoin, this )
);
if ( ! TableGroupJoinProducer.class.isInstance( joinedPart ) ) {
throw new HibernateException( "Expecting joined model part to implement TableGroupJoinProducer - " + joinedPart );
}
final NavigablePath joinedPath;
final String explicitAlias = sqmJoin.getExplicitAlias();
if ( explicitAlias == null ) {
joinedPath = sqmJoinNavigablePath;
}
else {
joinedPath = parentNavigablePath.append( sqmJoin.getAttribute().getName() );
}
joinedTableGroupJoin = ( (TableGroupJoinProducer) joinedPart ).createTableGroupJoin(
joinedPath,
lhsTableGroup,
sqmJoin.getExplicitAlias(),
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
determineLockMode( sqmJoin.getExplicitAlias() ),
this
);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
lhsTableGroup.addTableGroupJoin( joinedTableGroupJoin );
fromClauseIndex.register( sqmJoin, joinedTableGroup );
joinedPath = parentNavigablePath.append( sqmJoin.getAttribute().getName() );
}
joinedTableGroupJoin = ( (TableGroupJoinProducer) joinedPart ).createTableGroupJoin(
joinedPath,
lhsTableGroup,
sqmJoin.getExplicitAlias(),
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
determineLockMode( sqmJoin.getExplicitAlias() ),
this
);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
lhsTableGroup.addTableGroupJoin( joinedTableGroupJoin );
fromClauseIndex.register( sqmJoin, joinedTableGroup );
}
// add any additional join restrictions

View File

@ -6,13 +6,18 @@
*/
package org.hibernate.sql.ast.spi;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlTreeCreationException;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.ast.tree.update.Assignment;
/**
@ -38,6 +43,31 @@ public abstract class AbstractSqlAstTranslator
return affectedTableNames;
}
// @Override
// protected void renderTableGroup(TableGroup tableGroup) {
// super.renderTableGroup( tableGroup );
// ModelPartContainer modelPart = tableGroup.getModelPart();
//// if ( modelPart instanceof AbstractEntityPersister ) {
//// String[] querySpaces = (String[]) ( (AbstractEntityPersister) modelPart ).getQuerySpaces();
//// for ( int i = 0; i < querySpaces.length; i++ ) {
//// registerAffectedTable( querySpaces[i] );
//// }
//// }
// }
// @Override
// protected void renderTableGroup(TableGroup tableGroup, Predicate predicate) {
// super.renderTableGroup( tableGroup, predicate );
// ModelPartContainer modelPart = tableGroup.getModelPart();
//// if ( modelPart instanceof AbstractEntityPersister ) {
//// String[] querySpaces = (String[]) ( (AbstractEntityPersister) modelPart ).getQuerySpaces();
//// for ( int i = 0; i < querySpaces.length; i++ ) {
//// registerAffectedTable( querySpaces[i] );
//// }
//// }
// }
@Override
protected void renderTableReference(TableReference tableReference) {
super.renderTableReference( tableReference );

View File

@ -52,67 +52,6 @@ public class EmbeddedCircularFetchTests {
// - `org.hibernate.orm.test.fetch.circular.onetoone`
// - `org.hibernate.orm.test.fetch.circular.manytoone`
// @Test
// @TestForIssue(jiraKey = "HHH-9642")
// public void testEmbeddedAndOneToManyHql(SessionFactoryScope scope) {
// scope.inTransaction(
// session -> {
// InternetProvider provider = new InternetProvider();
// provider.setBrandName( "Fido" );
// LegalStructure structure = new LegalStructure();
// structure.setCountry( "Canada" );
// structure.setName( "Rogers" );
// provider.setOwner( structure );
// session.persist( provider );
// Manager manager = new Manager();
// manager.setName( "Bill" );
// manager.setEmployer( provider );
// structure.getTopManagement().add( manager );
// session.persist( manager );
// }
// );
//
// scope.inTransaction(
// session -> {
// InternetProvider internetProviderQueried =
// (InternetProvider) session.createQuery( "from InternetProvider" ).uniqueResult();
// assertFalse( Hibernate.isInitialized( internetProviderQueried.getOwner().getTopManagement() ) );
//
// }
// );
//
// scope.inTransaction(
// session -> {
// InternetProvider internetProviderQueried =
// (InternetProvider) session.createQuery(
// "from InternetProvider i join fetch i.owner.topManagement" )
// .uniqueResult();
// assertTrue( Hibernate.isInitialized( internetProviderQueried.getOwner().getTopManagement() ) );
//
// }
// );
//
// InternetProvider provider = scope.fromTransaction(
// session -> {
// InternetProvider internetProviderQueried =
// (InternetProvider) session.createQuery(
// "from InternetProvider i join fetch i.owner o join fetch o.topManagement" )
// .uniqueResult();
// assertTrue( Hibernate.isInitialized( internetProviderQueried.getOwner().getTopManagement() ) );
// return internetProviderQueried;
// }
// );
//
// scope.inTransaction(
// session -> {
// InternetProvider internetProvider = session.get( InternetProvider.class, provider.getId() );
// Manager manager = internetProvider.getOwner().getTopManagement().iterator().next();
// session.delete( manager );
// session.delete( internetProvider );
// }
// );
// }
@Test
@TestForIssue(jiraKey = "HHH-9642")
public void testCircularFetchAcrossComponent(SessionFactoryScope scope) {
@ -141,20 +80,10 @@ public class EmbeddedCircularFetchTests {
}
);
// scope.inTransaction(
// session -> {
// InternetProvider internetProviderQueried =
// (InternetProvider) session.createQuery( "from InternetProvider" ).uniqueResult();
// assertFalse( Hibernate.isInitialized( internetProviderQueried.getOwner().getTopManagement() ) );
//
// }
// );
scope.inTransaction(
session -> {
session.getSessionFactory().getStatistics().clear();
final RootEntity result = session.createQuery(
// "from RootEntity r join fetch r.intermediateComponent.leaves",
"from RootEntity r " +
"join fetch r.intermediateComponent.leaves l " +
"join fetch l.rootEntity",
@ -166,28 +95,6 @@ public class EmbeddedCircularFetchTests {
assertThat( session.getSessionFactory().getStatistics().getPrepareStatementCount(), is( 1L ) );
}
);
// InternetProvider provider = scope.fromTransaction(
// session -> {
// InternetProvider internetProviderQueried =
// (InternetProvider) session.createQuery(
// "from InternetProvider i join fetch i.owner o join fetch o.topManagement" )
// .uniqueResult();
// LegalStructure owner = internetProviderQueried.getOwner();
// assertTrue( Hibernate.isInitialized( owner ));
// assertTrue( Hibernate.isInitialized( owner.getTopManagement() ) );
// return internetProviderQueried;
// }
// );
//
// scope.inTransaction(
// session -> {
// InternetProvider internetProvider = session.get( InternetProvider.class, provider.getId() );
// Manager manager = internetProvider.getOwner().getTopManagement().iterator().next();
// session.delete( manager );
// session.delete( internetProvider );
// }
// );
}
@Entity( name = "RootEntity" )

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.cid;
package org.hibernate.orm.test.cid;
import java.math.BigDecimal;
import java.util.Calendar;
@ -29,10 +29,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
*/
@DomainModel(
xmlMappings = {
"org/hibernate/test/cid/Customer.hbm.xml",
"org/hibernate/test/cid/Order.hbm.xml",
"org/hibernate/test/cid/LineItem.hbm.xml",
"org/hibernate/test/cid/Product.hbm.xml"
"org/hibernate/orm/test/cid/Customer.hbm.xml",
"org/hibernate/orm/test/cid/Order.hbm.xml",
"org/hibernate/orm/test/cid/LineItem.hbm.xml",
"org/hibernate/orm/test/cid/Product.hbm.xml"
}
)
@SessionFactory(statementInspectorClass = SQLStatementInspector.class)
@ -97,7 +97,7 @@ public class CompositeIdTest {
session -> {
Order o = session.get( Order.class, new Order.Id( "C111", 0 ) );
statementInspector.assertExecutedCount( 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0, "join", 1 );
assertEquals( o.getTotal().intValue(), 2 );
o.getCustomer().getName();
}
@ -136,12 +136,13 @@ public class CompositeIdTest {
statementInspector.assertExecutedCount( 1 );
statementInspector.clear();
iter = session.createQuery( "from Order o join o.lineItems li" ).list().iterator();
statementInspector.assertExecutedCount( 1 );
statementInspector.assertExecutedCount( 2 );
statementInspector.clear();
while ( iter.hasNext() ) {
Object[] stuff = (Object[]) iter.next();
assertTrue( stuff.length == 2 );
Order order = (Order) iter.next();
assertTrue( Hibernate.isInitialized( order.getLineItems() ) );
}
statementInspector.assertExecutedCount( 1 );
statementInspector.assertExecutedCount( 0 );
}
);
@ -150,42 +151,97 @@ public class CompositeIdTest {
session -> {
Customer c = session.get( Customer.class, "C111" );
statementInspector.assertExecutedCount( 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 0 );
statementInspector.assertNumberOfOccurrenceInQuery( 0, "join", 0 );
statementInspector.clear();
Order o2 = new Order( c );
o2.setOrderDate( Calendar.getInstance() );
statementInspector.assertExecutedCount( 2 );
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 0 );
statementInspector.assertNumberOfOccurrenceInQuery( 1,"join", 0 );
statementInspector.assertExecutedCount( 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0, "join", 1 );
statementInspector.clear();
session.flush();
statementInspector.assertExecutedCount( 4 );
statementInspector.assertNumberOfOccurrenceInQuery( 0,"select", 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 0 );
statementInspector.assertNumberOfOccurrenceInQuery( 1,"insert", 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 2,"update", 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 3,"update", 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0, "select", 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0, "join", 0 );
statementInspector.assertIsInsert( 1 );
statementInspector.assertIsUpdate( 2 );
statementInspector.assertIsUpdate( 3 );
statementInspector.clear();
LineItem li2 = new LineItem( o2, p2 );
li2.setQuantity( 5 );
statementInspector.clear();
List bigOrders = session.createQuery( "from Order o where o.total>10.0" ).list();
statementInspector.assertExecutedCount( 3 );
statementInspector.assertNumberOfOccurrenceInQuery( 0,"select", 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 0 );
statementInspector.assertNumberOfOccurrenceInQuery( 1,"insert", 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 2,"select", 2 );
statementInspector.assertNumberOfOccurrenceInQuery( 3,"join", 0 );
statementInspector.assertNumberOfOccurrenceInQuery( 0, "select", 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 0, "join", 0 );
statementInspector.assertIsInsert( 1 );
statementInspector.assertNumberOfOccurrenceInQuery( 2, "select", 2 );
statementInspector.assertNumberOfOccurrenceInQuery( 3, "join", 0 );
assertEquals( bigOrders.size(), 1 );
}
);
}
@Test
public void testNonLazyFetch_2(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
Product p = new Product();
p.setProductId( "A123" );
p.setDescription( "nipple ring" );
p.setPrice( new BigDecimal( 1.0 ) );
p.setNumberAvailable( 1004 );
session.persist( p );
Product p2 = new Product();
p2.setProductId( "X525" );
p2.setDescription( "nose stud" );
p2.setPrice( new BigDecimal( 3.0 ) );
p2.setNumberAvailable( 105 );
session.persist( p2 );
Customer c = new Customer();
c.setAddress( "St Kilda Rd, MEL, 3000" );
c.setName( "Virginia" );
c.setCustomerId( "C111" );
session.persist( c );
Order o = new Order( c );
o.setOrderDate( Calendar.getInstance() );
LineItem li = new LineItem( o, p );
li.setQuantity( 2 );
}
);
scope.inTransaction(
session -> {
Order o = (Order) session.createQuery(
"from Order o left join fetch o.lineItems li left join fetch li.product p" )
.uniqueResult();
assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
LineItem li = (LineItem) o.getLineItems().iterator().next();
assertTrue( Hibernate.isInitialized( li ) );
assertTrue( Hibernate.isInitialized( li.getProduct() ) );
}
);
// scope.inTransaction(
// session -> {
// Order o = (Order) session.createQuery( "from Order o" ).uniqueResult();
// assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
// LineItem li = (LineItem) o.getLineItems().iterator().next();
// assertTrue( Hibernate.isInitialized( li ) );
// assertFalse( Hibernate.isInitialized( li.getProduct() ) );
// }
// );
}
@Test
public void testNonLazyFetch(SessionFactoryScope scope) {
scope.inTransaction(

View File

@ -18,7 +18,7 @@
-->
<hibernate-mapping package="org.hibernate.test.cid">
<hibernate-mapping package="org.hibernate.orm.test.cid">
<class name="Customer">

View File

@ -6,7 +6,7 @@
*/
//$Id: Customer.java 4806 2004-11-25 14:37:00Z steveebersole $
package org.hibernate.test.cid;
package org.hibernate.orm.test.cid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.GregorianCalendar;

View File

@ -22,7 +22,7 @@
-->
<hibernate-mapping package="org.hibernate.test.cid">
<hibernate-mapping package="org.hibernate.orm.test.cid">
<class name="LineItem">

View File

@ -6,7 +6,7 @@
*/
//$Id: LineItem.java 4806 2004-11-25 14:37:00Z steveebersole $
package org.hibernate.test.cid;
package org.hibernate.orm.test.cid;
import java.io.Serializable;
/**

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.cid">
<hibernate-mapping package="org.hibernate.orm.test.cid">
<!--

View File

@ -6,7 +6,7 @@
*/
//$Id: Order.java 4806 2004-11-25 14:37:00Z steveebersole $
package org.hibernate.test.cid;
package org.hibernate.orm.test.cid;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;

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.cid">
<hibernate-mapping package="org.hibernate.orm.test.cid">
<!--

View File

@ -6,7 +6,7 @@
*/
//$Id: Product.java 4806 2004-11-25 14:37:00Z steveebersole $
package org.hibernate.test.cid;
package org.hibernate.orm.test.cid;
import java.math.BigDecimal;
/**

View File

@ -72,11 +72,11 @@ import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.test.cid.Customer;
import org.hibernate.test.cid.LineItem;
import org.hibernate.test.cid.LineItem.Id;
import org.hibernate.test.cid.Order;
import org.hibernate.test.cid.Product;
import org.hibernate.orm.test.cid.Customer;
import org.hibernate.orm.test.cid.LineItem;
import org.hibernate.orm.test.cid.LineItem.Id;
import org.hibernate.orm.test.cid.Order;
import org.hibernate.orm.test.cid.Product;
import org.junit.Test;
import org.hamcrest.CoreMatchers;

View File

@ -8,6 +8,7 @@ package org.hibernate.testing.jdbc;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import org.hibernate.resource.jdbc.spi.StatementInspector;
@ -52,4 +53,14 @@ public class SQLStatementInspector implements StatementInspector {
int actual = query.split( " " + toCheck + " ", -1 ).length - 1;
assertThat( "number of " + toCheck,actual, is( expectedNumberOfOccurrences ) );
}
public void assertIsInsert(int queryNumber) {
String query = sqlQueries.get( queryNumber );
assertTrue( query.toLowerCase( Locale.ROOT ).startsWith( "insert" ) );
}
public void assertIsUpdate(int queryNumber) {
String query = sqlQueries.get( queryNumber );
assertTrue( query.toLowerCase( Locale.ROOT ).startsWith( "update" ) );
}
}