[hibernate-commits] Hibernate SVN: r21177 - in core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211: testsuite/src/test/java/org/hibernate/test/criteria and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Feb 12 19:47:59 EST 2015


Author: gbadner
Date: 2015-02-12 19:47:59 -0500 (Thu, 12 Feb 2015)
New Revision: 21177

Added:
   core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Address.java
   core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OrderAddress.java
   core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OrderContact.java
Modified:
   core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/core/src/main/java/org/hibernate/loader/JoinWalker.java
   core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Order.hbm.xml
   core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Order.java
   core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OuterJoinCriteriaTest.java
Log:
JBPAPP-11211 HHH-9597 : Criteria creates invalid Column aliases

Modified: core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/core/src/main/java/org/hibernate/loader/JoinWalker.java
===================================================================
--- core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/core/src/main/java/org/hibernate/loader/JoinWalker.java	2015-02-13 00:25:28 UTC (rev 21176)
+++ core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/core/src/main/java/org/hibernate/loader/JoinWalker.java	2015-02-13 00:47:59 UTC (rev 21177)
@@ -978,7 +978,11 @@
 				);
 				buf.append(selectFragment);
 				if ( joinable.consumesEntityAlias() ) entityAliasCount++;
-				if ( joinable.consumesCollectionAlias() && join.getJoinType()==JoinFragment.LEFT_OUTER_JOIN ) collectionAliasCount++;
+				if ( joinable.consumesCollectionAlias() &&
+						join.getJoinType()==JoinFragment.LEFT_OUTER_JOIN &&
+						!join.hasRestriction() ) {
+					collectionAliasCount++;
+				}
 				if (
 					i<associations.size()-1 &&
 					selectFragment.trim().length()>0

Added: core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Address.java
===================================================================
--- core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Address.java	                        (rev 0)
+++ core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Address.java	2015-02-13 00:47:59 UTC (rev 21177)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2015, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.test.criteria;
+
+/**
+ * @author Gail Badner
+ */
+public class Address {
+	private int addressId;
+
+	public int getAddressId() {
+		return addressId;
+	}
+
+	private String addressText;
+
+	public String getAddressText() {
+		return addressText;
+	}
+
+	public void setAddressText(String addressText) {
+		this.addressText = addressText;
+	}
+}

Modified: core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Order.hbm.xml
===================================================================
--- core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Order.hbm.xml	2015-02-13 00:25:28 UTC (rev 21176)
+++ core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Order.hbm.xml	2015-02-13 00:47:59 UTC (rev 21177)
@@ -1,22 +1,53 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-
-<hibernate-mapping  package="org.hibernate.test.criteria">
-  <class name="Order" table="t_order">
-    <id name="orderId" column="order_id" type="int" unsaved-value="0" access="field" >
-      <generator class="identity" />
-    </id>
-    <set name="orderLines" cascade="all-delete-orphan" access="field" inverse="true" fetch="select">
-      <key column="order_id" />
-      <one-to-many class="OrderLine" />
-    </set>
-  </class>
-  <class name="OrderLine" table="order_line">
-    <id name="lineId" column="order_line_id" type="int" unsaved-value="0" access="field" >
-      <generator class="identity" />
-    </id>
-    <many-to-one name="order" column="order_id" class="Order" />
-    <property name="articleId" column="article_id" type="string" />
-  </class>
-</hibernate-mapping>
-
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping  package="org.hibernate.test.criteria">
+  <class name="Order" table="t_order">
+    <id name="orderId" column="order_id" type="int" unsaved-value="0" access="field" >
+      <generator class="increment" />
+    </id>
+    <many-to-one name="orderAddress" cascade="all"/>
+    <set name="orderLines" cascade="all-delete-orphan" access="field" inverse="true" fetch="select">
+      <key column="order_id" />
+      <one-to-many class="OrderLine" />
+    </set>
+    <set name="orderContacts" cascade="all-delete-orphan" access="field" fetch="select">
+        <key column="order_id" />
+        <many-to-many class="OrderContact" />
+    </set>
+  </class>
+  <class name="OrderLine" table="order_line">
+    <id name="lineId" column="order_line_id" type="int" unsaved-value="0" access="field" >
+      <generator class="increment" />
+    </id>
+    <many-to-one name="order" column="order_id" class="Order" />
+    <property name="articleId" column="article_id" type="string" />
+  </class>
+  <class name="OrderContact" table="order_contact">
+    <id name="contactId" column="order_contact_id" type="int" unsaved-value="0" access="field" >
+      <generator class="increment" />
+    </id>
+    <property name="contact" column="contact" type="string" />
+    <set name="orders" access="field" inverse="true" fetch="select">
+          <key column="contact_id" />
+          <many-to-many class="Order" />
+    </set>
+  </class>
+  <class name="OrderAddress">
+      <id name="orderAddressId" type="int" unsaved-value="0" access="field" >
+          <generator class="increment" />
+      </id>
+      <many-to-one name="deliveryAddress" class="Address" cascade="all" />
+      <set name="notifiedAddresses" cascade="all"  inverse="false" fetch="select" >
+          <key column="orderAddressId"/>
+          <one-to-many class="Address"/>
+      </set>
+  </class>
+   <class name="Address">
+        <id name="addressId" column="address_id" type="int" unsaved-value="0" access="field" >
+            <generator class="increment" />
+        </id>
+        <property name="addressText"/>
+    </class>
+</hibernate-mapping>
+

Modified: core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Order.java
===================================================================
--- core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Order.java	2015-02-13 00:25:28 UTC (rev 21176)
+++ core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/Order.java	2015-02-13 00:47:59 UTC (rev 21177)
@@ -23,28 +23,51 @@
  */
 package org.hibernate.test.criteria;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
 
 public class Order {
 
-  private int orderId;
+	private int orderId;
 
-  public int getOrderId() {
+	public int getOrderId() {
     return orderId;
   }
 
-  private Set<OrderLine> orderLines = new HashSet<OrderLine>();
+	private Set<OrderLine> orderLines = new HashSet<OrderLine>();
 
-  public Set<OrderLine> getLines() {
+	public Set<OrderLine> getLines() {
     return Collections.unmodifiableSet(orderLines);
   }
 
-  public void addLine(OrderLine orderLine){
-    orderLine.setOrder(this);
-    this.orderLines.add(orderLine);
-  }
-  
-  public String toString() {
+	public void addLine(OrderLine orderLine){
+		orderLine.setOrder(this);
+		this.orderLines.add(orderLine);
+	}
+
+	private Set<OrderContact> orderContacts = new HashSet<OrderContact>();
+
+	public Set<OrderContact> getContacts() {
+		return Collections.unmodifiableSet(orderContacts);
+	}
+
+	public void addContact(OrderContact orderContact){
+		orderContact.getOrders().add( this );
+		this.orderContacts.add(orderContact);
+	}
+
+	public OrderAddress orderAddress;
+
+	public OrderAddress getOrderAddress() {
+		return orderAddress;
+	}
+
+	public void setOrderAddress(OrderAddress orderAddress) {
+		this.orderAddress = orderAddress;
+	}
+
+	public String toString() {
     return "" + getOrderId() + " - " + getLines();
   }
-}
\ No newline at end of file
+}

Added: core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OrderAddress.java
===================================================================
--- core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OrderAddress.java	                        (rev 0)
+++ core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OrderAddress.java	2015-02-13 00:47:59 UTC (rev 21177)
@@ -0,0 +1,60 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2015, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.test.criteria;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class OrderAddress {
+
+	private int orderAddressId;
+
+	public int getOrderAddressId() {
+		return orderAddressId;
+	}
+
+	private Address deliveryAddress;
+
+	public Address getDeliveryAddress() {
+		return deliveryAddress;
+	}
+
+	public void setDeliveryAddress(Address deliveryAddress) {
+		this.deliveryAddress = deliveryAddress;
+	}
+
+	private Set<Address> notifiedAddresses = new HashSet<Address>();
+
+	public Set<Address> getNotifiedAddresses() {
+    	return notifiedAddresses;
+  	}
+
+	public void setNotifiedAddresses(Set<Address> notifiedAddresses) {
+		this.notifiedAddresses = notifiedAddresses;
+	}
+
+	public String toString() {
+    return "" + orderAddressId + " - " + getDeliveryAddress() + " - " + getNotifiedAddresses();
+  }
+}

Added: core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OrderContact.java
===================================================================
--- core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OrderContact.java	                        (rev 0)
+++ core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OrderContact.java	2015-02-13 00:47:59 UTC (rev 21177)
@@ -0,0 +1,56 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.test.criteria;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class OrderContact {
+
+  private int contactId = 0;
+  private Set<Order> orders = new HashSet<Order>();
+  
+  private String contact;
+
+  
+  public int getContactId() {
+    return contactId;
+  }
+
+  public Set<Order> getOrders() {
+    return orders;
+  }  
+
+  public String getContact() {
+    return contact;
+  }
+
+  public void setContact(String contact) {
+    this.contact = contact;
+  }
+  
+  public String toString() {
+    return "[" + getContactId() + ":" + getContact() + "]";
+  }
+}
\ No newline at end of file

Modified: core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OuterJoinCriteriaTest.java
===================================================================
--- core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OuterJoinCriteriaTest.java	2015-02-13 00:25:28 UTC (rev 21176)
+++ core/patches/hibernate-3.3.2.GA_CP05_JBPAPP-11211/testsuite/src/test/java/org/hibernate/test/criteria/OuterJoinCriteriaTest.java	2015-02-13 00:47:59 UTC (rev 21177)
@@ -27,11 +27,13 @@
 import java.util.List;
 import java.util.Map;
 
+import org.hibernate.CacheMode;
 import org.hibernate.Criteria;
 import org.hibernate.Session;
 import org.hibernate.criterion.Restrictions;
 import org.hibernate.junit.functional.FunctionalTestCase;
 import org.hibernate.sql.JoinFragment;
+import org.hibernate.criterion.CriteriaSpecification;
 
 /**
  * @author Mattias Jiderhamn
@@ -81,7 +83,24 @@
 		s.getTransaction().commit();
 		s.close();
 	}
+	
+	public void testWithNonNullAndNullRestrictions() {
+		Session s = openSession();
+		s.getTransaction().begin();
+		
+		Criteria rootCriteria = s.createCriteria(Order.class, "order");
+			
+		rootCriteria.createCriteria("order.orderLines", "line", CriteriaSpecification.LEFT_JOIN)
+				.add(Restrictions.eq("line.articleId", "3000"));
 
+		rootCriteria.createCriteria("order.orderContacts", "contact", CriteriaSpecification.LEFT_JOIN).add(Restrictions.eq("contact.contact", "Contact1"));
+		
+		List orders = rootCriteria.list();
+		
+		s.getTransaction().commit();
+		s.close();
+	}
+
 	public void testSubcriteriaWithNonNullRestrictionsAliasToEntityMap() {
 		Session s = openSession();
 		s.getTransaction().begin();
@@ -367,6 +386,190 @@
 		s.close();
 	}
 
+	public void testMultipleSubCriteriaRestrictionsOnCollections() {
+		Session s = openSession();
+		s.getTransaction().begin();
+
+		Criteria rootCriteria = s.createCriteria(Order.class, "order");
+		rootCriteria.createCriteria( "order.orderLines", "line", JoinFragment.LEFT_OUTER_JOIN )
+				.add(Restrictions.eq("line.articleId", "3000"));
+		rootCriteria.createCriteria( "order.orderContacts", "contact", JoinFragment.LEFT_OUTER_JOIN )
+				.add(Restrictions.eq("contact.contact", "Contact1"));
+		// result should be order1, because that's the only Order with:
+		// 1) orderLines containing an OrderLine with articleId == "3000"
+		// and 2) orderContacts containing an OrderContact with contact == "Contact1"
+		// Since both restrictions are in subcriteria, both collections should be non-filtered
+		// (i.e. includes all elements in both collections)
+		Order result = (Order) rootCriteria.uniqueResult();
+		assertEquals( order1.getOrderId(), result.getOrderId() );
+		assertEquals( 2, result.getContacts().size() );
+		assertEquals( 2, result.getLines().size() );
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testMultipleRootCriteriaRestrictionsOnCollections() {
+		Session s = openSession();
+		s.getTransaction().begin();
+
+		Criteria rootCriteria = s.createCriteria(Order.class, "order");
+		rootCriteria.createAlias( "order.orderLines", "line", JoinFragment.LEFT_OUTER_JOIN )
+				.add(Restrictions.eq("line.articleId", "3000"));
+		rootCriteria.createAlias("order.orderContacts", "contact", JoinFragment.LEFT_OUTER_JOIN)
+				.add( Restrictions.eq( "contact.contact", "Contact1" ) );
+		// result should be order1, because that's the only Order with:
+		// 1) orderLines containing an OrderLine with articleId == "3000"
+		// and 2) orderContacts containing an OrderContact with contact == "Contact1"
+		// Since both restrictions are in root criteria, both collections should be filtered
+		// to contain only the elements that satisfy the restrictions.
+		Order result = (Order) rootCriteria.uniqueResult();
+		assertEquals( order1.getOrderId(), result.getOrderId() );
+		assertEquals( 1, result.getLines().size() );
+		assertEquals( "3000", result.getLines().iterator().next().getArticleId() );
+		assertEquals( 1, result.getContacts().size() );
+		assertEquals( "Contact1", result.getContacts().iterator().next().getContact() );
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testRootAndSubCriteriaRestrictionsOnCollections() {
+		// the result of all Criteria in this test will be order1, because that's the only Order with:
+		// 1) orderLines containing an OrderLine with articleId == "3000"
+		// and 2) orderContacts containing an OrderContact with contact == "Contact1"
+
+		Session s = openSession();
+		// set to CacheMode.IGNORE to avoid HHH-2003
+		s.setCacheMode( CacheMode.IGNORE );
+		s.getTransaction().begin();
+		Criteria rootCriteria = s.createCriteria(Order.class, "order");
+		rootCriteria.createCriteria("order.orderContacts", "contact", JoinFragment.LEFT_OUTER_JOIN)
+				.add( Restrictions.eq( "contact.contact", "Contact1" ) );
+		rootCriteria.createAlias("order.orderLines", "line", JoinFragment.LEFT_OUTER_JOIN)
+				.add(Restrictions.eq("line.articleId", "3000"));
+		// Since restriction on orderLines is on root criteria, that collection should be filtered.
+		// Since restriction on orderContacts is on a subcriteria, that collection should be
+		// non-filtered (contain all its elements)
+		Order result = (Order) rootCriteria.uniqueResult();
+		assertEquals( order1.getOrderId(), result.getOrderId() );
+		assertEquals( 1, result.getLines().size() );
+		assertEquals( "3000", result.getLines().iterator().next().getArticleId() );
+		assertEquals( 2, result.getContacts().size() );
+		s.getTransaction().commit();
+		s.close();
+
+		// The following should have the same result as the previous, since it has the same
+		// restrictions applied in reverse order.
+
+		s = openSession();
+		// set to CacheMode.IGNORE to avoid HHH-2003
+		s.setCacheMode( CacheMode.IGNORE );
+		s.getTransaction().begin();
+		rootCriteria = s.createCriteria(Order.class, "order");
+		rootCriteria.createCriteria("order.orderContacts", "contact", JoinFragment.LEFT_OUTER_JOIN)
+				.add(Restrictions.eq("contact.contact", "Contact1"));
+		rootCriteria.createAlias( "order.orderLines", "line", JoinFragment.LEFT_OUTER_JOIN )
+				.add(Restrictions.eq("line.articleId", "3000"));
+		// Since restriction on orderLines is on root criteria, that collection should be filtered.
+		// Since restriction on orderContacts is on a subcriteria, that collection should be
+		// non-filtered (contain all its elements)
+		result = (Order) rootCriteria.uniqueResult();
+		assertEquals( order1.getOrderId(), result.getOrderId() );
+		assertEquals( 1, result.getLines().size() );
+		assertEquals( "3000", result.getLines().iterator().next().getArticleId() );
+		assertEquals( 2, result.getContacts().size() );
+		s.getTransaction().commit();
+		s.close();
+
+		// Even though the following seem redundant, there was a failure due to HHH-9597
+		// that reproduced when filtering Order.orderContacts, but not order.orderLines.
+
+		s = openSession();
+		// set to CacheMode.IGNORE to avoid HHH-2003
+		s.setCacheMode( CacheMode.IGNORE );
+		s.getTransaction().begin();
+		rootCriteria = s.createCriteria(Order.class, "order");
+		rootCriteria.createAlias( "order.orderContacts", "contact", JoinFragment.LEFT_OUTER_JOIN )
+				.add(Restrictions.eq("contact.contact", "Contact1"));
+		rootCriteria.createCriteria( "order.orderLines", "line", JoinFragment.LEFT_OUTER_JOIN )
+				.add(Restrictions.eq("line.articleId", "3000"));
+		// Since restriction on orderContacts is on root criteria, that collection should be filtered.
+		// Since restriction on orderLines is on a subcriteria, that collection should be
+		// non-filtered (contain all its elements)
+		result = (Order) rootCriteria.uniqueResult();
+		assertEquals( order1.getOrderId(), result.getOrderId() );
+		assertEquals( 2, result.getLines().size() );
+		assertEquals( 1, result.getContacts().size() );
+		assertEquals( "Contact1", result.getContacts().iterator().next().getContact() );
+		s.getTransaction().commit();
+		s.close();
+
+		// The following should have the same result as the previous, since it has the same
+		// restrictions applied in reverse order.
+
+		s = openSession();
+		// set to CacheMode.IGNORE to avoid HHH-2003
+		s.setCacheMode( CacheMode.IGNORE );
+		s.getTransaction().begin();
+		rootCriteria = s.createCriteria(Order.class, "order").setCacheable( false );
+		rootCriteria.createCriteria( "order.orderLines", "line", JoinFragment.LEFT_OUTER_JOIN )
+				.add(Restrictions.eq("line.articleId", "3000"));
+		rootCriteria.createAlias( "order.orderContacts", "contact", JoinFragment.LEFT_OUTER_JOIN )
+				.add(Restrictions.eq("contact.contact", "Contact1"));
+		result = (Order) rootCriteria.uniqueResult();
+		assertEquals( order1.getOrderId(), result.getOrderId() );
+		assertEquals( 2, result.getLines().size() );
+		assertEquals( 1, result.getContacts().size() );
+		assertEquals( "Contact1", result.getContacts().iterator().next().getContact() );
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testSubCriteriaRestrictionsOnCollectionsNestedInManyToOne() {
+		// the result of all Criteria in this test will be order1, because that's the only Order with:
+		// 1) orderContacts containing an OrderContact with contact == "Contact1"
+		// and 2) orderAddress.notifiedAddresses containing an Address with addressText == "over the rainbow"
+
+		Session s = openSession();
+		s.getTransaction().begin();
+		Criteria rootCriteria = s.createCriteria(Order.class, "order");
+		rootCriteria.createCriteria("order.orderContacts", "contact", JoinFragment.LEFT_OUTER_JOIN)
+				.add( Restrictions.eq( "contact.contact", "Contact1" ) );
+		rootCriteria.createCriteria( "order.orderAddress", "orderAddress", JoinFragment.LEFT_OUTER_JOIN )
+				.createCriteria( "orderAddress.notifiedAddresses", "notifiedAddress", JoinFragment.LEFT_OUTER_JOIN )
+				.add( Restrictions.eq( "notifiedAddress.addressText", "over the rainbow" ) );
+
+		// Since restrictions are on subcriteria, the collections should n on orderLines is on root criteria, that collection should be filtered.
+		// Since restriction on orderContacts is on a subcriteria, that collection should be
+		// non-filtered (contain all its elements)
+		Order result = (Order) rootCriteria.uniqueResult();
+		assertEquals( order1.getOrderId(), result.getOrderId() );
+		assertEquals( 2, result.getContacts().size() );
+		assertEquals( 2, result.getOrderAddress().getNotifiedAddresses().size() );
+		s.getTransaction().commit();
+		s.close();
+
+		// The following should have the same result as the previous, since it has the same
+		// restrictions applied in reverse order.
+
+		s = openSession();
+		s.getTransaction().begin();
+		rootCriteria = s.createCriteria(Order.class, "order");
+		rootCriteria.createCriteria( "order.orderAddress", "orderAddress", JoinFragment.LEFT_OUTER_JOIN )
+				.createCriteria( "orderAddress.notifiedAddresses", "notifiedAddress", JoinFragment.LEFT_OUTER_JOIN )
+				.add( Restrictions.eq( "notifiedAddress.addressText", "over the rainbow" ) );
+		rootCriteria.createCriteria("order.orderContacts", "contact", JoinFragment.LEFT_OUTER_JOIN)
+				.add( Restrictions.eq( "contact.contact", "Contact1" ) );
+		// Since restrictions are on subcriteria, the collections should n on orderLines is on root criteria, that collection should be filtered.
+		// Since restriction on orderContacts is on a subcriteria, that collection should be
+		// non-filtered (contain all its elements)
+		result = (Order) rootCriteria.uniqueResult();
+		assertEquals( order1.getOrderId(), result.getOrderId() );
+		assertEquals( 2, result.getContacts().size() );
+		assertEquals( 2, result.getOrderAddress().getNotifiedAddresses().size() );
+		s.getTransaction().commit();
+		s.close();
+	}
+
 	protected void prepareTest() {
 		Session s = openSession();
 		s.getTransaction().begin();
@@ -379,10 +582,33 @@
 		line = new OrderLine();
 		line.setArticleId( "3000" );
 		order1.addLine( line );
+		
+		OrderContact contact = new OrderContact();
+		contact.setContact( "Contact1" );
+		order1.addContact( contact );
+		contact = new OrderContact();
+		contact.setContact( "Contact2" );
+		order1.addContact( contact );
+		
 		s.persist( order1 );
 
+		OrderAddress orderAddress = new OrderAddress();
+		Address address = new Address();
+		address.setAddressText( "over the rainbow" );
+		orderAddress.setDeliveryAddress( address );
+		Address otherAddress = new Address();
+		otherAddress.setAddressText( "other place" );
+		orderAddress.getNotifiedAddresses().add( address );
+		orderAddress.getNotifiedAddresses().add( otherAddress );
+		order1.setOrderAddress( orderAddress );
+
+		s.persist( order1 );
+
 		// Order with no lines
 		order2 = new Order();
+		contact = new OrderContact();
+		contact.setContact( "Contact1" );
+		order2.addContact( contact );
 		s.persist( order2 );
 
 		// Order with non-matching line
@@ -399,11 +625,21 @@
 	protected void cleanupTest() {
 		Session s = openSession();
 		s.getTransaction().begin();
+		s.delete( order1 );
+		s.delete( order2 );
+		s.delete( order3 );
+		/*
+		List orders = s.createQuery( "from Order" ).list();
 
-		s.createQuery( "delete from OrderLine" ).executeUpdate();
+		for( Object order : orders ) {
+			s.delete( order );
+		}
+		//s.createQuery( "delete from OrderContact" ).executeUpdate();
 
-		s.createQuery( "delete from Order" ).executeUpdate();
+		//s.createQuery( "delete from OrderLine" ).executeUpdate();
 
+		//s.createQuery( "delete from Order" ).executeUpdate();
+        */
 		s.getTransaction().commit();
 		s.close();
 	}
@@ -411,4 +647,4 @@
 	private static boolean isBlank(String s) {
 		return s == null || s.trim().length() == 0;
 	}
-}
\ No newline at end of file
+}



More information about the hibernate-commits mailing list