Skip to content

Commit c99e0bc

Browse files
committed
HHH-17105 Add test for issue
1 parent 00209bb commit c99e0bc

File tree

1 file changed

+247
-0
lines changed

1 file changed

+247
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
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.orm.test.mapping.manytomany;
8+
9+
import java.util.ArrayList;
10+
import java.util.Comparator;
11+
import java.util.HashSet;
12+
import java.util.List;
13+
import java.util.Set;
14+
15+
import org.hibernate.annotations.SQLInsert;
16+
import org.hibernate.annotations.WhereJoinTable;
17+
18+
import org.hibernate.testing.jdbc.SQLStatementInspector;
19+
import org.hibernate.testing.orm.junit.DomainModel;
20+
import org.hibernate.testing.orm.junit.Jira;
21+
import org.hibernate.testing.orm.junit.SessionFactory;
22+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
23+
import org.junit.jupiter.api.AfterAll;
24+
import org.junit.jupiter.api.BeforeAll;
25+
import org.junit.jupiter.api.Test;
26+
27+
import jakarta.persistence.Column;
28+
import jakarta.persistence.Entity;
29+
import jakarta.persistence.Id;
30+
import jakarta.persistence.JoinColumn;
31+
import jakarta.persistence.JoinTable;
32+
import jakarta.persistence.ManyToMany;
33+
import jakarta.persistence.OrderColumn;
34+
import jakarta.persistence.Table;
35+
36+
import static org.assertj.core.api.Assertions.assertThat;
37+
38+
/**
39+
* @author Marco Belladelli
40+
*/
41+
@DomainModel( annotatedClasses = {
42+
ManyToManySQLJoinTableRestrictionTest.Project.class,
43+
ManyToManySQLJoinTableRestrictionTest.User.class,
44+
ManyToManySQLJoinTableRestrictionTest.ProjectUsers.class,
45+
} )
46+
@SessionFactory( useCollectingStatementInspector = true )
47+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17105" )
48+
public class ManyToManySQLJoinTableRestrictionTest {
49+
@BeforeAll
50+
public void setUp(SessionFactoryScope scope) {
51+
scope.inTransaction( session -> {
52+
final User user1 = new User( "user1" );
53+
final Project project1 = new Project( "p1" );
54+
project1.getManagers().add( user1 );
55+
project1.getMembers().add( user1 );
56+
final Project project2 = new Project( "p2" );
57+
project2.getMembers().add( user1 );
58+
session.persist( user1 );
59+
session.persist( project1 );
60+
session.persist( project2 );
61+
final User user2 = new User( "user2" );
62+
final User user3 = new User( "user3" );
63+
final Project project3 = new Project( "p3" );
64+
project3.getMembers().add( user2 );
65+
project3.getMembers().add( user3 );
66+
project3.getManagers().add( user2 );
67+
project3.getOrderedUsers().add(user3);
68+
project3.getOrderedUsers().add(user2);
69+
session.persist( user2 );
70+
session.persist( user3 );
71+
session.persist( project3 );
72+
} );
73+
}
74+
75+
@AfterAll
76+
public void tearDown(SessionFactoryScope scope) {
77+
scope.inTransaction( session -> {
78+
session.createMutationQuery( "delete from Project" ).executeUpdate();
79+
session.createMutationQuery( "delete from User" ).executeUpdate();
80+
} );
81+
}
82+
83+
@Test
84+
public void testJoinTableRemoveEmptyCollection(SessionFactoryScope scope) {
85+
final SQLStatementInspector inspector = scope.getCollectingStatementInspector();
86+
scope.inTransaction( session -> {
87+
final Project p1 = session.find( Project.class, "p1" );
88+
p1.getManagers().remove( p1.getManagers().iterator().next() );
89+
assertThat( p1.getManagers() ).isEmpty();
90+
inspector.clear();
91+
} );
92+
assertThat( inspector.getSqlQueries() ).hasSize( 1 );
93+
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "manager" );
94+
scope.inTransaction( session -> {
95+
final User user1 = session.find( User.class, "user1" );
96+
assertThat( user1.getManagedProjects() ).isEmpty();
97+
assertThat( user1.getOtherProjects().stream().map( Project::getName ) ).contains( "p1", "p2" );
98+
} );
99+
}
100+
101+
@Test
102+
public void testJoinTableRemoveNonEmptyCollection(SessionFactoryScope scope) {
103+
final SQLStatementInspector inspector = scope.getCollectingStatementInspector();
104+
scope.inTransaction( session -> {
105+
final User user = session.find( User.class, "user2" );
106+
final Project p3 = session.find( Project.class, "p3" );
107+
p3.getMembers().remove( user );
108+
assertThat( p3.getMembers() ).isNotEmpty();
109+
inspector.clear();
110+
} );
111+
assertThat( inspector.getSqlQueries() ).hasSize( 1 );
112+
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "member" );
113+
scope.inTransaction( session -> {
114+
final User user2 = session.find( User.class, "user2" );
115+
assertThat( user2.getOtherProjects() ).isEmpty();
116+
assertThat( user2.getManagedProjects().stream().map( Project::getName ) ).contains( "p3" );
117+
} );
118+
}
119+
120+
@Test
121+
public void testJoinTableUpdate(SessionFactoryScope scope) {
122+
final SQLStatementInspector inspector = scope.getCollectingStatementInspector();
123+
scope.inTransaction( session -> {
124+
final Project p3 = session.find( Project.class, "p3" );
125+
assertThat( p3.getOrderedUsers().stream().map( User::getName ) ).containsExactly( "user3", "user2" );
126+
p3.getOrderedUsers().sort( Comparator.comparing( User::getName ) );
127+
inspector.clear();
128+
} );
129+
assertThat( inspector.getSqlQueries() ).hasSize( 2 );
130+
assertThat( inspector.getSqlQueries().get( 0 ) ).contains( "order_col is not null" );
131+
assertThat( inspector.getSqlQueries().get( 1 ) ).contains( "order_col is not null" );
132+
scope.inTransaction( session -> {
133+
final Project p3 = session.find( Project.class, "p3" );
134+
assertThat( p3.getOrderedUsers().stream().map( User::getName ) ).containsExactly( "user2", "user3" );
135+
} );
136+
}
137+
138+
@Entity( name = "Project" )
139+
@Table( name = "t_project" )
140+
public static class Project {
141+
@Id
142+
private String name;
143+
144+
@ManyToMany
145+
@JoinTable(
146+
name = "project_users",
147+
joinColumns = { @JoinColumn( name = "project_id" ) },
148+
inverseJoinColumns = { @JoinColumn( name = "user_id" ) }
149+
)
150+
@WhereJoinTable( clause = "role = 'manager'" )
151+
@SQLInsert( sql = "insert into project_users (project_id, user_id, role) values (?, ?, 'manager')" )
152+
private Set<User> managers = new HashSet<>();
153+
154+
@ManyToMany
155+
@JoinTable(
156+
name = "project_users",
157+
joinColumns = { @JoinColumn( name = "project_id" ) },
158+
inverseJoinColumns = { @JoinColumn( name = "user_id" ) }
159+
)
160+
@WhereJoinTable( clause = "role = 'member'" )
161+
@SQLInsert( sql = "insert into project_users (project_id, user_id, role) values (?, ?, 'member')" )
162+
private Set<User> members = new HashSet<>();
163+
164+
@ManyToMany
165+
@JoinTable(
166+
name = "ordered_users",
167+
joinColumns = { @JoinColumn( name = "project_id" ) },
168+
inverseJoinColumns = { @JoinColumn( name = "user_id" ) }
169+
)
170+
@WhereJoinTable( clause = "order_col is not null" )
171+
@OrderColumn( name = "order_col" )
172+
private List<User> orderedUsers = new ArrayList<>();
173+
174+
public Project() {
175+
}
176+
177+
public Project(String name) {
178+
this.name = name;
179+
}
180+
181+
public String getName() {
182+
return name;
183+
}
184+
185+
public Set<User> getManagers() {
186+
return managers;
187+
}
188+
189+
public Set<User> getMembers() {
190+
return members;
191+
}
192+
193+
public List<User> getOrderedUsers() {
194+
return orderedUsers;
195+
}
196+
}
197+
198+
@Entity( name = "ProjectUsers" )
199+
@Table( name = "project_users" )
200+
public static class ProjectUsers {
201+
@Id
202+
@Column( name = "project_id" )
203+
private String projectId;
204+
205+
@Id
206+
@Column( name = "user_id" )
207+
private String userId;
208+
209+
@Id
210+
@Column( name = "role" )
211+
private String role;
212+
}
213+
214+
@Entity( name = "User" )
215+
@Table( name = "t_user" )
216+
public static class User {
217+
@Id
218+
private String name;
219+
220+
@ManyToMany( mappedBy = "managers" )
221+
@WhereJoinTable( clause = "role = 'manager'" )
222+
private Set<Project> managedProjects = new HashSet<>();
223+
224+
@ManyToMany( mappedBy = "members" )
225+
@WhereJoinTable( clause = "role = 'member'" )
226+
private Set<Project> otherProjects = new HashSet<>();
227+
228+
public User() {
229+
}
230+
231+
public User(String name) {
232+
this.name = name;
233+
}
234+
235+
public String getName() {
236+
return name;
237+
}
238+
239+
public Set<Project> getManagedProjects() {
240+
return managedProjects;
241+
}
242+
243+
public Set<Project> getOtherProjects() {
244+
return otherProjects;
245+
}
246+
}
247+
}

0 commit comments

Comments
 (0)