HHH-2049 : LEFT OUTER JOIN subcriteria filters children (Mattias Jiderhamn)
This commit is contained in:
parent
a6b8d62209
commit
f0c2488d91
|
@ -414,6 +414,7 @@ public class CriteriaImpl implements Criteria, Serializable {
|
|||
private LockMode lockMode;
|
||||
private int joinType;
|
||||
private Criterion withClause;
|
||||
private boolean hasRestriction;
|
||||
|
||||
// Constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -423,6 +424,7 @@ public class CriteriaImpl implements Criteria, Serializable {
|
|||
this.parent = parent;
|
||||
this.joinType = joinType;
|
||||
this.withClause = withClause;
|
||||
this.hasRestriction = withClause != null;
|
||||
CriteriaImpl.this.subcriteriaList.add( this );
|
||||
}
|
||||
|
||||
|
@ -477,10 +479,14 @@ public class CriteriaImpl implements Criteria, Serializable {
|
|||
return this.withClause;
|
||||
}
|
||||
|
||||
public boolean hasRestriction() {
|
||||
return hasRestriction;
|
||||
}
|
||||
|
||||
// Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
public Criteria add(Criterion expression) {
|
||||
hasRestriction = true;
|
||||
CriteriaImpl.this.add(this, expression);
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -205,6 +205,10 @@ public class JoinWalker {
|
|||
}
|
||||
}
|
||||
|
||||
protected boolean hasRestriction(PropertyPath path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected String getWithClause(PropertyPath path) {
|
||||
return "";
|
||||
}
|
||||
|
@ -239,6 +243,7 @@ public class JoinWalker {
|
|||
subalias,
|
||||
joinType,
|
||||
getWithClause(path),
|
||||
hasRestriction( path ),
|
||||
getFactory(),
|
||||
loadQueryInfluencers.getEnabledFilters()
|
||||
);
|
||||
|
@ -877,7 +882,9 @@ public class JoinWalker {
|
|||
Iterator iter = associations.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
|
||||
if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN && oj.getJoinable().isCollection() ) {
|
||||
if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN &&
|
||||
oj.getJoinable().isCollection() &&
|
||||
! oj.hasRestriction() ) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
@ -1012,7 +1019,7 @@ public class JoinWalker {
|
|||
else {
|
||||
|
||||
QueryableCollection collPersister = (QueryableCollection) oj.getJoinable();
|
||||
if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN ) {
|
||||
if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN && ! oj.hasRestriction() ) {
|
||||
//it must be a collection fetch
|
||||
collectionPersisters[j] = collPersister;
|
||||
collectionOwners[j] = oj.getOwner(associations);
|
||||
|
|
|
@ -51,6 +51,7 @@ public final class OuterJoinableAssociation {
|
|||
private final int joinType;
|
||||
private final String on;
|
||||
private final Map enabledFilters;
|
||||
private final boolean hasRestriction;
|
||||
|
||||
public static OuterJoinableAssociation createRoot(
|
||||
AssociationType joinableType,
|
||||
|
@ -64,6 +65,7 @@ public final class OuterJoinableAssociation {
|
|||
alias,
|
||||
JoinFragment.LEFT_OUTER_JOIN,
|
||||
null,
|
||||
false,
|
||||
factory,
|
||||
CollectionHelper.EMPTY_MAP
|
||||
);
|
||||
|
@ -77,6 +79,7 @@ public final class OuterJoinableAssociation {
|
|||
String rhsAlias,
|
||||
int joinType,
|
||||
String withClause,
|
||||
boolean hasRestriction,
|
||||
SessionFactoryImplementor factory,
|
||||
Map enabledFilters) throws MappingException {
|
||||
this.propertyPath = propertyPath;
|
||||
|
@ -89,6 +92,7 @@ public final class OuterJoinableAssociation {
|
|||
this.rhsColumns = JoinHelper.getRHSColumnNames(joinableType, factory);
|
||||
this.on = joinableType.getOnCondition(rhsAlias, factory, enabledFilters)
|
||||
+ ( withClause == null || withClause.trim().length() == 0 ? "" : " and ( " + withClause + " )" );
|
||||
this.hasRestriction = hasRestriction;
|
||||
this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application
|
||||
}
|
||||
|
||||
|
@ -138,6 +142,10 @@ public final class OuterJoinableAssociation {
|
|||
return joinable;
|
||||
}
|
||||
|
||||
public boolean hasRestriction() {
|
||||
return hasRestriction;
|
||||
}
|
||||
|
||||
public int getOwner(final List associations) {
|
||||
if ( isOneToOne() || isCollection() ) {
|
||||
return getPosition(lhsAlias, associations);
|
||||
|
|
|
@ -278,5 +278,8 @@ public class CriteriaJoinWalker extends AbstractEntityJoinWalker {
|
|||
protected String getWithClause(PropertyPath path) {
|
||||
return translator.getWithClause( path.getFullPath() );
|
||||
}
|
||||
|
||||
|
||||
protected boolean hasRestriction(PropertyPath path) {
|
||||
return translator.hasRestriction( path.getFullPath() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -674,5 +674,12 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
|
|||
final Criterion crit = (Criterion)this.withClauseMap.get(path);
|
||||
return crit == null ? null : crit.toSqlString(getCriteria(path), this);
|
||||
}
|
||||
|
||||
|
||||
public boolean hasRestriction(String path)
|
||||
{
|
||||
final CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) getCriteria( path );
|
||||
return crit == null ? false : crit.hasRestriction();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.*;
|
||||
|
||||
public class Order {
|
||||
|
||||
private int orderId;
|
||||
|
||||
public int getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
private Set<OrderLine> orderLines = new HashSet<OrderLine>();
|
||||
|
||||
public Set<OrderLine> getLines() {
|
||||
return Collections.unmodifiableSet(orderLines);
|
||||
}
|
||||
|
||||
public void addLine(OrderLine orderLine){
|
||||
orderLine.setOrder(this);
|
||||
this.orderLines.add(orderLine);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + getOrderId() + " - " + getLines();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
public class OrderLine {
|
||||
|
||||
private int lineId = 0;
|
||||
|
||||
private Order order;
|
||||
|
||||
private String articleId;
|
||||
|
||||
|
||||
public int getLineId() {
|
||||
return lineId;
|
||||
}
|
||||
|
||||
public Order getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public String getArticleId() {
|
||||
return articleId;
|
||||
}
|
||||
|
||||
public void setOrder(Order order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public void setArticleId(String articleId) {
|
||||
this.articleId = articleId;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[" + getLineId() + ":" + getArticleId() + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,428 @@
|
|||
/*
|
||||
* 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.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.hibernate.sql.JoinFragment;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @author Mattias Jiderhamn
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class OuterJoinCriteriaTest extends BaseCoreFunctionalTestCase {
|
||||
private Order order1;
|
||||
private Order order2;
|
||||
private Order order3;
|
||||
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "criteria/Order.hbm.xml" };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubcriteriaWithNonNullRestrictions() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
Criteria rootCriteria = s.createCriteria( Order.class );
|
||||
Criteria subCriteria = rootCriteria.createCriteria( "orderLines", JoinFragment.LEFT_OUTER_JOIN );
|
||||
assertNotSame( rootCriteria, subCriteria );
|
||||
|
||||
// add restrictions to subCriteria, ensuring we stay on subCriteria
|
||||
assertSame( subCriteria, subCriteria.add( Restrictions.eq( "articleId", "3000" ) ) );
|
||||
|
||||
List orders = rootCriteria.list();
|
||||
|
||||
// order1 and order3 should be returned because each has articleId == "3000"
|
||||
// both should have their full collection
|
||||
assertEquals( 2, orders.size() );
|
||||
for ( Iterator it = orders.iterator(); it.hasNext(); ) {
|
||||
Order o = (Order) it.next();
|
||||
if ( order1.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( order1.getLines().size(), o.getLines().size() );
|
||||
}
|
||||
else if ( order3.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( order3.getLines().size(), o.getLines().size() );
|
||||
}
|
||||
else {
|
||||
fail( "unknown order" );
|
||||
}
|
||||
}
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubcriteriaWithNonNullRestrictionsAliasToEntityMap() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
Criteria rootCriteria = s.createCriteria( Order.class, "o" );
|
||||
Criteria subCriteria = rootCriteria.createCriteria( "orderLines", "ol", JoinFragment.LEFT_OUTER_JOIN );
|
||||
assertNotSame( rootCriteria, subCriteria );
|
||||
|
||||
// add restriction to subCriteria, ensuring we stay on subCriteria
|
||||
assertSame( subCriteria, subCriteria.add( Restrictions.eq( "articleId", "3000" ) ) );
|
||||
|
||||
List orders = rootCriteria.setResultTransformer( Criteria.ALIAS_TO_ENTITY_MAP ).list();
|
||||
|
||||
// order1 and order3 should be returned because each has articleId == "3000";
|
||||
// the orders should both should have their full collection;
|
||||
assertEquals( 2, orders.size() );
|
||||
for ( Iterator it = orders.iterator(); it.hasNext(); ) {
|
||||
Map map = (Map) it.next();
|
||||
Order o = ( Order ) map.get( "o" );
|
||||
// the orderLine returned from the map should have articleId = "3000"
|
||||
OrderLine ol = ( OrderLine ) map.get( "ol" );
|
||||
if ( order1.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( order1.getLines().size(), o.getLines().size() );
|
||||
assertEquals( "3000", ol.getArticleId() );
|
||||
}
|
||||
else if ( order3.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( order3.getLines().size(), o.getLines().size() );
|
||||
assertEquals( "3000", ol.getArticleId() );
|
||||
}
|
||||
else {
|
||||
fail( "unknown order" );
|
||||
}
|
||||
}
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubcriteriaWithNullOrNonNullRestrictions() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
Criteria rootCriteria = s.createCriteria( Order.class );
|
||||
Criteria subCriteria = rootCriteria.createCriteria( "orderLines", JoinFragment.LEFT_OUTER_JOIN );
|
||||
assertNotSame( rootCriteria, subCriteria );
|
||||
|
||||
// add restrictions to subCriteria, ensuring we stay on subCriteria
|
||||
// add restriction to subCriteria, ensuring we stay on subCriteria
|
||||
assertSame(
|
||||
subCriteria,
|
||||
subCriteria.add(
|
||||
Restrictions.or(
|
||||
Restrictions.isNull( "articleId" ), // Allow null
|
||||
Restrictions.eq( "articleId", "1000" )
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
List orders = rootCriteria.list();
|
||||
|
||||
// order1 should be returned because it has an orderline with articleId == "1000";
|
||||
// order2 should be returned because it has no orderlines
|
||||
assertEquals( 2, orders.size() );
|
||||
for ( Iterator it = orders.iterator(); it.hasNext(); ) {
|
||||
Order o = ( Order ) it.next();
|
||||
if ( order1.getOrderId() == o.getOrderId() ) {
|
||||
// o.getLines() should contain all of its orderLines
|
||||
assertEquals( order1.getLines().size(), o.getLines().size() );
|
||||
}
|
||||
else if ( order2.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( order2.getLines() , o.getLines() );
|
||||
assertTrue( o.getLines().isEmpty() );
|
||||
}
|
||||
else {
|
||||
fail( "unknown order" );
|
||||
}
|
||||
}
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubcriteriaWithNullOrNonNullRestrictionsAliasToEntityMap() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
Criteria rootCriteria = s.createCriteria( Order.class, "o" );
|
||||
Criteria subCriteria = rootCriteria.createCriteria( "orderLines", "ol", JoinFragment.LEFT_OUTER_JOIN );
|
||||
assertNotSame( rootCriteria, subCriteria );
|
||||
|
||||
// add restriction to subCriteria, ensuring we stay on subCriteria
|
||||
assertSame(
|
||||
subCriteria,
|
||||
subCriteria.add(
|
||||
Restrictions.or(
|
||||
Restrictions.isNull( "ol.articleId" ), // Allow null
|
||||
Restrictions.eq( "ol.articleId", "1000" )
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
List orders = rootCriteria.setResultTransformer( Criteria.ALIAS_TO_ENTITY_MAP ).list();
|
||||
|
||||
// order1 should be returned because it has an orderline with articleId == "1000";
|
||||
// order2 should be returned because it has no orderlines
|
||||
assertEquals( 2, orders.size() );
|
||||
for ( Iterator it = orders.iterator(); it.hasNext(); ) {
|
||||
Map map = (Map) it.next();
|
||||
Order o = ( Order ) map.get( "o" );
|
||||
// the orderLine returned from the map should either be null or have articleId = "1000"
|
||||
OrderLine ol = ( OrderLine ) map.get( "ol" );
|
||||
if ( order1.getOrderId() == o.getOrderId() ) {
|
||||
// o.getLines() should contain all of its orderLines
|
||||
assertEquals( order1.getLines().size(), o.getLines().size() );
|
||||
assertNotNull( ol );
|
||||
assertEquals( "1000", ol.getArticleId() );
|
||||
}
|
||||
else if ( order2.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( order2.getLines() , o.getLines() );
|
||||
assertTrue( o.getLines().isEmpty() );
|
||||
assertNull( ol );
|
||||
}
|
||||
else {
|
||||
fail( "unknown order" );
|
||||
}
|
||||
}
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubcriteriaWithClauseAliasToEntityMap() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
Criteria rootCriteria = s.createCriteria( Order.class, "o" );
|
||||
Criteria subCriteria = rootCriteria.createCriteria(
|
||||
"orderLines",
|
||||
"ol", JoinFragment.LEFT_OUTER_JOIN,
|
||||
Restrictions.or(
|
||||
Restrictions.isNull( "ol.articleId" ), // Allow null
|
||||
Restrictions.eq( "ol.articleId", "1000" )
|
||||
)
|
||||
);
|
||||
assertNotSame( rootCriteria, subCriteria );
|
||||
|
||||
List orders = rootCriteria.setResultTransformer( Criteria.ALIAS_TO_ENTITY_MAP ).list();
|
||||
|
||||
// all orders should be returned (via map.get( "o" )) with their full collections;
|
||||
assertEquals( 3, orders.size() );
|
||||
for ( Iterator it = orders.iterator(); it.hasNext(); ) {
|
||||
Map map = ( Map ) it.next();
|
||||
Order o = ( Order ) map.get( "o" );
|
||||
// the orderLine returned from the map should either be null or have articleId = "1000"
|
||||
OrderLine ol = ( OrderLine ) map.get( "ol" );
|
||||
if ( order1.getOrderId() == o.getOrderId() ) {
|
||||
// o.getLines() should contain all of its orderLines
|
||||
assertEquals( order1.getLines().size(), o.getLines().size() );
|
||||
assertNotNull( ol );
|
||||
assertEquals( "1000", ol.getArticleId() );
|
||||
}
|
||||
else if ( order2.getOrderId() == o.getOrderId() ) {
|
||||
assertTrue( o.getLines().isEmpty() );
|
||||
assertNull( ol );
|
||||
}
|
||||
else if ( order3.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( order3.getLines().size(), o.getLines().size() );
|
||||
assertNull( ol);
|
||||
}
|
||||
else {
|
||||
fail( "unknown order" );
|
||||
}
|
||||
}
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliasWithNonNullRestrictions() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
Criteria rootCriteria = s.createCriteria( Order.class );
|
||||
// create alias, ensuring we stay on the root criteria
|
||||
assertSame( rootCriteria, rootCriteria.createAlias( "orderLines", "ol", JoinFragment.LEFT_OUTER_JOIN ) );
|
||||
|
||||
// add restrictions to rootCriteria
|
||||
assertSame( rootCriteria, rootCriteria.add( Restrictions.eq( "ol.articleId", "3000" ) ) );
|
||||
|
||||
List orders = rootCriteria.list();
|
||||
|
||||
// order1 and order3 should be returned because each has articleId == "3000"
|
||||
// the contained collections should only have the orderLine with articleId == "3000"
|
||||
assertEquals( 2, orders.size() );
|
||||
for ( Iterator it = orders.iterator(); it.hasNext(); ) {
|
||||
Order o = (Order) it.next();
|
||||
if ( order1.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( 1, o.getLines().size() );
|
||||
assertEquals( "3000", ( ( OrderLine ) o.getLines().iterator().next() ).getArticleId() );
|
||||
}
|
||||
else if ( order3.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( 1, o.getLines().size() );
|
||||
assertEquals( "3000", ( ( OrderLine ) o.getLines().iterator().next() ).getArticleId() );
|
||||
}
|
||||
else {
|
||||
fail( "unknown order" );
|
||||
}
|
||||
}
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliasWithNullOrNonNullRestrictions() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
Criteria rootCriteria = s.createCriteria( Order.class );
|
||||
// create alias, ensuring we stay on the root criteria
|
||||
assertSame( rootCriteria, rootCriteria.createAlias( "orderLines", "ol", JoinFragment.LEFT_OUTER_JOIN ) );
|
||||
|
||||
// add restrictions to rootCriteria
|
||||
assertSame(
|
||||
rootCriteria,
|
||||
rootCriteria.add(
|
||||
Restrictions.or(
|
||||
Restrictions.isNull( "ol.articleId" ), // Allow null
|
||||
Restrictions.eq( "ol.articleId", "1000" )
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
List orders = rootCriteria.list();
|
||||
|
||||
// order1 should be returned because it has an orderline with articleId == "1000";
|
||||
// the contained collection for order1 should only have the orderLine with articleId == "1000";
|
||||
// order2 should be returned because it has no orderlines
|
||||
assertEquals( 2, orders.size() );
|
||||
for ( Object order : orders ) {
|
||||
Order o = (Order) order;
|
||||
if ( order1.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( "1000", ( ( OrderLine ) o.getLines().iterator().next() ).getArticleId() );
|
||||
}
|
||||
else if ( order2.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( 0, o.getLines().size() );
|
||||
}
|
||||
else {
|
||||
fail( "unknown order" );
|
||||
}
|
||||
}
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonNullSubcriteriaRestrictionsOnRootCriteria() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
Criteria rootCriteria = s.createCriteria( Order.class );
|
||||
Criteria subCriteria = rootCriteria.createCriteria( "orderLines", "ol", JoinFragment.LEFT_OUTER_JOIN );
|
||||
assertNotSame( rootCriteria, subCriteria );
|
||||
|
||||
// add restriction to rootCriteria (NOT subcriteria)
|
||||
assertSame( rootCriteria, rootCriteria.add( Restrictions.eq( "ol.articleId", "3000" ) ) );
|
||||
|
||||
List orders = rootCriteria.list();
|
||||
|
||||
// results should be the same as testAliasWithNonNullRestrictions() (using Criteria.createAlias())
|
||||
// order1 and order3 should be returned because each has articleId == "3000"
|
||||
// the contained collections should only have the orderLine with articleId == "3000"
|
||||
assertEquals( 2, orders.size() );
|
||||
for ( Iterator it = orders.iterator(); it.hasNext(); ) {
|
||||
Order o = (Order) it.next();
|
||||
if ( order1.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( 1, o.getLines().size() );
|
||||
assertEquals( "3000", ( ( OrderLine ) o.getLines().iterator().next() ).getArticleId() );
|
||||
}
|
||||
else if ( order3.getOrderId() == o.getOrderId() ) {
|
||||
assertEquals( 1, o.getLines().size() );
|
||||
assertEquals( "3000", ( ( OrderLine ) o.getLines().iterator().next() ).getArticleId() );
|
||||
}
|
||||
else {
|
||||
fail( "unknown order" );
|
||||
}
|
||||
}
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
protected void prepareTest() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
// Order with one mathing line
|
||||
order1 = new Order();
|
||||
OrderLine line = new OrderLine();
|
||||
line.setArticleId( "1000" );
|
||||
order1.addLine( line );
|
||||
line = new OrderLine();
|
||||
line.setArticleId( "3000" );
|
||||
order1.addLine( line );
|
||||
s.persist( order1 );
|
||||
|
||||
// Order with no lines
|
||||
order2 = new Order();
|
||||
s.persist( order2 );
|
||||
|
||||
// Order with non-matching line
|
||||
order3 = new Order();
|
||||
line = new OrderLine();
|
||||
line.setArticleId( "3000" );
|
||||
order3.addLine( line );
|
||||
s.persist( order3 );
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
protected void cleanupTest() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
s.createQuery( "delete from OrderLine" ).executeUpdate();
|
||||
|
||||
s.createQuery( "delete from Order" ).executeUpdate();
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
private static boolean isBlank(String s) {
|
||||
return s == null || s.trim().length() == 0;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue