Skip to content

Commit 8cd51b4

Browse files
janariovladmihalcea
authored andcommitted
HHH-7355 - Added support to join with of many-to-many relation
1 parent 438e964 commit 8cd51b4

File tree

4 files changed

+270
-1
lines changed

4 files changed

+270
-1
lines changed

hibernate-core/src/main/java/org/hibernate/loader/JoinWalker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ private void addAssociationToJoinTree(
232232
aliasedLhsColumns,
233233
subalias,
234234
joinType,
235-
getWithClause( path ),
235+
joinable.consumesEntityAlias() ? getWithClause( path ) : "",
236236
hasRestriction( path ),
237237
getFactory(),
238238
loadQueryInfluencers.getEnabledFilters()
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.test.criteria.many_to_many;
8+
9+
import java.util.LinkedHashSet;
10+
import java.util.List;
11+
import java.util.Set;
12+
13+
import org.hibernate.Criteria;
14+
import org.hibernate.Session;
15+
import org.hibernate.Transaction;
16+
import org.hibernate.criterion.Restrictions;
17+
import org.hibernate.sql.JoinType;
18+
19+
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
20+
import org.junit.Test;
21+
22+
import static org.junit.Assert.assertFalse;
23+
import static org.junit.Assert.assertTrue;
24+
25+
/**
26+
* @author Janario Oliveira
27+
*/
28+
public class CriteriaManyToManyTest extends BaseNonConfigCoreFunctionalTestCase {
29+
30+
private Seller[] persist(String prefix) {
31+
Session session = openSession();
32+
33+
Transaction tx = session.beginTransaction();
34+
Seller seller1 = new Seller( prefix + "-seller1" );
35+
Seller seller2 = new Seller( prefix + "-seller2" );
36+
37+
Customer customer1 = new Customer( prefix + "-customer1" );
38+
Customer customer2 = new Customer( prefix + "-customer2" );
39+
Customer customer3 = new Customer( prefix + "-customer3" );
40+
41+
seller1.addCustomer( customer1 );
42+
seller1.addCustomer( customer2 );
43+
seller2.addCustomer( customer2 );
44+
seller2.addCustomer( customer3 );
45+
46+
session.persist( customer1 );
47+
session.persist( customer2 );
48+
session.persist( customer3 );
49+
session.persist( seller1 );
50+
session.persist( seller2 );
51+
52+
tx.commit();
53+
session.close();
54+
return new Seller[] {seller1, seller2};
55+
}
56+
57+
@Test
58+
public void testJoinTable() {
59+
Seller[] sellers = persist( "join-table" );
60+
Seller seller1 = sellers[0];
61+
Seller seller2 = sellers[1];
62+
63+
Session session = openSession();
64+
65+
Criteria criteria = session.createCriteria( Seller.class, "s" );
66+
criteria.createCriteria(
67+
"s.soldTo",
68+
"c",
69+
JoinType.INNER_JOIN,
70+
Restrictions.eq( "name", "join-table-customer1" )
71+
);
72+
criteria.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY );
73+
@SuppressWarnings("unchecked")
74+
List<Seller> results = criteria.list();
75+
assertTrue( results.size() == 1 );
76+
assertTrue( results.contains( seller1 ) );
77+
assertFalse( results.contains( seller2 ) );
78+
79+
80+
criteria = session.createCriteria( Seller.class, "s" );
81+
criteria.createCriteria(
82+
"s.soldTo",
83+
"c",
84+
JoinType.INNER_JOIN,
85+
Restrictions.eq( "name", "join-table-customer2" )
86+
);
87+
criteria.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY );
88+
89+
@SuppressWarnings("unchecked")
90+
List<Seller> results2 = criteria.list();
91+
assertTrue( results2.size() == 2 );
92+
assertTrue( results2.contains( seller1 ) );
93+
assertTrue( results2.contains( seller2 ) );
94+
95+
session.close();
96+
}
97+
98+
@Test
99+
public void testMappedBy() {
100+
Set<Customer> customersAll = new LinkedHashSet<Customer>();
101+
Seller[] sellers = persist( "mappedby" );
102+
customersAll.addAll( sellers[0].getSoldTo() );
103+
customersAll.addAll( sellers[1].getSoldTo() );
104+
105+
Customer[] customers = customersAll.toArray( new Customer[customersAll.size()] );
106+
Customer customer1 = customers[0];
107+
Customer customer2 = customers[1];
108+
Customer customer3 = customers[2];
109+
110+
Session session = openSession();
111+
112+
Criteria criteria = session.createCriteria( Customer.class, "c" );
113+
criteria.createCriteria(
114+
"c.boughtFrom",
115+
"s",
116+
JoinType.INNER_JOIN,
117+
Restrictions.eq( "name", "mappedby-seller1" )
118+
);
119+
criteria.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY );
120+
@SuppressWarnings("unchecked")
121+
List<Customer> results = criteria.list();
122+
assertTrue( results.size() == 2 );
123+
assertTrue( results.contains( customer1 ) );
124+
assertTrue( results.contains( customer2 ) );
125+
assertFalse( results.contains( customer3 ) );
126+
127+
128+
criteria = session.createCriteria( Customer.class, "c" );
129+
criteria.createCriteria(
130+
"c.boughtFrom",
131+
"s",
132+
JoinType.INNER_JOIN,
133+
Restrictions.eq( "name", "mappedby-seller2" )
134+
);
135+
criteria.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY );
136+
@SuppressWarnings("unchecked")
137+
List<Customer> results2 = criteria.list();
138+
assertTrue( results2.size() == 2 );
139+
assertFalse( results2.contains( customer1 ) );
140+
assertTrue( results2.contains( customer2 ) );
141+
assertTrue( results2.contains( customer3 ) );
142+
143+
session.close();
144+
}
145+
146+
@Override
147+
protected Class[] getAnnotatedClasses() {
148+
return new Class[] {Seller.class, Customer.class};
149+
}
150+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.test.criteria.many_to_many;
8+
9+
import java.util.HashSet;
10+
import java.util.Set;
11+
import javax.persistence.Entity;
12+
import javax.persistence.GeneratedValue;
13+
import javax.persistence.Id;
14+
import javax.persistence.ManyToMany;
15+
16+
/**
17+
* @author Janario Oliveira
18+
*/
19+
@Entity
20+
public class Customer {
21+
@Id
22+
@GeneratedValue
23+
private Integer id;
24+
private String name;
25+
26+
@ManyToMany(mappedBy = "soldTo")
27+
private Set<Seller> boughtFrom = new HashSet<Seller>();
28+
29+
protected Customer() {
30+
}
31+
32+
public Customer(String name) {
33+
this.name = name;
34+
}
35+
36+
public Set<Seller> getBoughtFrom() {
37+
return boughtFrom;
38+
}
39+
40+
@Override
41+
public boolean equals(Object o) {
42+
if ( !( o instanceof Customer ) ) {
43+
return false;
44+
}
45+
46+
Customer customer = (Customer) o;
47+
return name.equals( customer.name );
48+
49+
}
50+
51+
@Override
52+
public int hashCode() {
53+
return name.hashCode();
54+
}
55+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.test.criteria.many_to_many;
8+
9+
import java.util.HashSet;
10+
import java.util.Set;
11+
import javax.persistence.Entity;
12+
import javax.persistence.GeneratedValue;
13+
import javax.persistence.Id;
14+
import javax.persistence.JoinColumn;
15+
import javax.persistence.JoinTable;
16+
import javax.persistence.ManyToMany;
17+
18+
/**
19+
* @author Janario Oliveira
20+
*/
21+
@Entity
22+
public class Seller {
23+
@Id
24+
@GeneratedValue
25+
private Integer id;
26+
private String name;
27+
28+
@ManyToMany
29+
@JoinTable(name = "seller_customer",
30+
joinColumns = @JoinColumn(name = "seller_id"),
31+
inverseJoinColumns = @JoinColumn(name = "customer_id"))
32+
private Set<Customer> soldTo = new HashSet<Customer>();
33+
34+
protected Seller() {
35+
}
36+
37+
public Seller(String name) {
38+
this.name = name;
39+
}
40+
41+
public Set<Customer> getSoldTo() {
42+
return soldTo;
43+
}
44+
45+
public void addCustomer(Customer customer) {
46+
customer.getBoughtFrom().add( this );
47+
soldTo.add( customer );
48+
}
49+
50+
@Override
51+
public boolean equals(Object o) {
52+
if ( !( o instanceof Seller ) ) {
53+
return false;
54+
}
55+
56+
Seller seller = (Seller) o;
57+
return name.equals( seller.name );
58+
}
59+
60+
@Override
61+
public int hashCode() {
62+
return name.hashCode();
63+
}
64+
}

0 commit comments

Comments
 (0)