From d2a796f04a27b88a9df12f148505f1744c13d6fe Mon Sep 17 00:00:00 2001 From: Etienne Miret Date: Sat, 7 Feb 2015 16:29:51 +0100 Subject: [PATCH] HHH-3813 Fix flush of the join table before a criteria query. --- .../criteria/CriteriaQueryTranslator.java | 16 +++++- .../test/flush/NativeCriteriaSyncTest.java | 55 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/flush/NativeCriteriaSyncTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java b/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java index 53fc9fb9b7..2db53897ef 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java @@ -38,6 +38,7 @@ import org.hibernate.hql.internal.ast.util.SessionFactoryHelper; import org.hibernate.internal.CriteriaImpl; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.PropertyMapping; import org.hibernate.persister.entity.Queryable; @@ -130,10 +131,23 @@ public class CriteriaQueryTranslator implements CriteriaQuery { } public Set getQuerySpaces() { - Set result = new HashSet(); + Set result = new HashSet<>(); for ( CriteriaInfoProvider info : criteriaInfoMap.values() ) { result.addAll( Arrays.asList( info.getSpaces() ) ); } + for ( final Map.Entry entry : associationPathCriteriaMap.entrySet() ) { + String path = entry.getKey(); + CriteriaImpl.Subcriteria crit = (CriteriaImpl.Subcriteria) entry.getValue(); + int index = path.lastIndexOf( '.' ); + if ( index > 0 ) { + path = path.substring( index + 1, path.length() ); + } + CriteriaInfoProvider info = criteriaInfoMap.get( crit.getParent() ); + CollectionPersister persister = getFactory().getMetamodel().collectionPersisters().get( info.getName() + "." + path ); + if ( persister != null ) { + result.addAll( Arrays.asList( persister.getCollectionSpaces() ) ); + } + } return result; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/flush/NativeCriteriaSyncTest.java b/hibernate-core/src/test/java/org/hibernate/test/flush/NativeCriteriaSyncTest.java new file mode 100644 index 0000000000..2175258f75 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/flush/NativeCriteriaSyncTest.java @@ -0,0 +1,55 @@ +/* + * 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 . + */ +package org.hibernate.test.flush; + +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.*; + +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.criterion.Restrictions; +import org.hibernate.test.hql.SimpleEntityWithAssociation; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * @author Etienne Miret + */ +public class NativeCriteriaSyncTest extends BaseCoreFunctionalTestCase { + + /** + * Tests that the join table of a many-to-many relationship is properly flushed before making a related Criteria + * query. + */ + @Test + @TestForIssue( jiraKey = "HHH-3813" ) + public void test() { + + + final SimpleEntityWithAssociation e1 = new SimpleEntityWithAssociation( "e1" ); + final SimpleEntityWithAssociation e2 = new SimpleEntityWithAssociation( "e2" ); + e1.getManyToManyAssociatedEntities().add( e2 ); + + doInHibernate( this::sessionFactory, session -> { + session.save( e1 ); + + final Criteria criteria = session.createCriteria( SimpleEntityWithAssociation.class ); + criteria.createCriteria( "manyToManyAssociatedEntities" ).add( Restrictions.eq( "name", "e2" ) ); + assertEquals( 1, criteria.list().size() ); + } ); + } + + @Override + protected String[] getMappings() { + return new String[] { "hql/SimpleEntityWithAssociation.hbm.xml" }; + } + +}