Skip to content

Commit f04762a

Browse files
Add integration test for QueryByExample match mode on associations.
Original Pull Request: #3794
1 parent 44c88db commit f04762a

File tree

3 files changed

+55
-15
lines changed

3 files changed

+55
-15
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/convert/QueryByExamplePredicateBuilder.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.springframework.dao.InvalidDataAccessApiUsageException;
3737
import org.springframework.data.domain.Example;
3838
import org.springframework.data.domain.ExampleMatcher;
39+
import org.springframework.data.domain.ExampleMatcher.MatchMode;
3940
import org.springframework.data.domain.ExampleMatcher.PropertyValueTransformer;
4041
import org.springframework.data.jpa.repository.query.EscapeCharacter;
4142
import org.springframework.data.support.ExampleMatcherAccessor;
@@ -105,9 +106,8 @@ public static <T> Predicate getPredicate(Root<T> root, CriteriaBuilder cb, Examp
105106
ExampleMatcher matcher = example.getMatcher();
106107

107108
List<Predicate> predicates = getPredicates("", cb, root, root.getModel(), example.getProbe(),
108-
example.getProbeType(), matcher, new ExampleMatcherAccessor(matcher),
109-
new PathNode("root", null, example.getProbe()),
110-
escapeCharacter);
109+
example.getProbeType(), matcher.getMatchMode(), new ExampleMatcherAccessor(matcher),
110+
new PathNode("root", null, example.getProbe()), escapeCharacter);
111111

112112
if (predicates.isEmpty()) {
113113
return null;
@@ -124,7 +124,7 @@ public static <T> Predicate getPredicate(Root<T> root, CriteriaBuilder cb, Examp
124124

125125
@SuppressWarnings({ "rawtypes", "unchecked" })
126126
static List<Predicate> getPredicates(String path, CriteriaBuilder cb, Path<?> from, ManagedType<?> type, Object value,
127-
Class<?> probeType, ExampleMatcher matcher, ExampleMatcherAccessor exampleAccessor, PathNode currentNode,
127+
Class<?> probeType, MatchMode matchMode, ExampleMatcherAccessor exampleAccessor, PathNode currentNode,
128128
EscapeCharacter escapeCharacter) {
129129

130130
List<Predicate> predicates = new ArrayList<>();
@@ -161,7 +161,7 @@ static List<Predicate> getPredicates(String path, CriteriaBuilder cb, Path<?> fr
161161

162162
predicates
163163
.addAll(getPredicates(currentPath, cb, from.get(attribute.getName()), (ManagedType<?>) attribute.getType(),
164-
attributeValue, probeType, matcher, exampleAccessor, currentNode, escapeCharacter));
164+
attributeValue, probeType, matchMode, exampleAccessor, currentNode, escapeCharacter));
165165
continue;
166166
}
167167

@@ -174,9 +174,9 @@ static List<Predicate> getPredicates(String path, CriteriaBuilder cb, Path<?> fr
174174
ClassUtils.getShortName(probeType), node));
175175
}
176176

177-
JoinType joinType = matcher.isAllMatching() ? JoinType.INNER : JoinType.LEFT;
177+
JoinType joinType = matchMode.equals(MatchMode.ALL) ? JoinType.INNER : JoinType.LEFT;
178178
predicates.addAll(getPredicates(currentPath, cb, ((From<?, ?>) from).join(attribute.getName(), joinType),
179-
(ManagedType<?>) attribute.getType(), attributeValue, probeType, matcher, exampleAccessor, node,
179+
(ManagedType<?>) attribute.getType(), attributeValue, probeType, matchMode, exampleAccessor, node,
180180
escapeCharacter));
181181

182182
continue;

spring-data-jpa/src/test/java/org/springframework/data/jpa/convert/QueryByExamplePredicateBuilderUnitTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ void likePatternsGetEscapedEnding() {
277277
verify(cb, times(1)).like(any(Expression.class), eq("%f\\\\o\\_o"), eq('\\'));
278278
}
279279

280-
@ParameterizedTest(name = "Matching {0} on association should join using JoinType.{1} ") // DATAJPA-3763
280+
@ParameterizedTest(name = "Matching {0} on association should join using JoinType.{1} ") // GH-3763
281281
@CsvSource({ "ALL, INNER", "ANY, LEFT" })
282282
void matchingAssociationShouldUseTheCorrectJoinType(MatchMode matchMode, JoinType expectedJoinType) {
283283

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/QueryByExampleIntegrationTests.java

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,44 @@
1515
*/
1616
package org.springframework.data.jpa.repository;
1717

18-
import static org.assertj.core.api.Assertions.*;
18+
import static org.assertj.core.api.Assertions.assertThat;
1919

2020
import jakarta.persistence.EntityManager;
2121
import jakarta.persistence.criteria.CriteriaBuilder;
2222
import jakarta.persistence.criteria.CriteriaQuery;
2323
import jakarta.persistence.criteria.Predicate;
2424
import jakarta.persistence.criteria.Root;
2525

26+
import java.util.List;
27+
2628
import org.junit.jupiter.api.AfterEach;
2729
import org.junit.jupiter.api.BeforeEach;
2830
import org.junit.jupiter.api.Test;
2931
import org.junit.jupiter.api.extension.ExtendWith;
3032
import org.springframework.beans.factory.annotation.Autowired;
3133
import org.springframework.data.domain.Example;
34+
import org.springframework.data.domain.ExampleMatcher;
3235
import org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder;
3336
import org.springframework.data.jpa.domain.sample.Role;
37+
import org.springframework.data.jpa.domain.sample.User;
3438
import org.springframework.data.jpa.repository.sample.RoleRepository;
39+
import org.springframework.data.jpa.repository.sample.UserRepository;
3540
import org.springframework.test.context.ContextConfiguration;
3641
import org.springframework.test.context.junit.jupiter.SpringExtension;
3742
import org.springframework.transaction.annotation.Transactional;
3843

3944
/**
4045
* @author Greg Turnquist
46+
* @author Christoph Strobl
4147
* @since 3.0
4248
*/
4349
@ExtendWith(SpringExtension.class)
4450
@ContextConfiguration({ "classpath:hibernate.xml", "classpath:config/namespace-application-context.xml" })
4551
@Transactional
4652
class QueryByExampleIntegrationTests {
4753

48-
@Autowired RoleRepository repository;
54+
@Autowired RoleRepository roleRepository;
55+
@Autowired UserRepository userRepository;
4956
@Autowired EntityManager em;
5057

5158
private Role drummer;
@@ -55,14 +62,14 @@ class QueryByExampleIntegrationTests {
5562
@BeforeEach
5663
void setUp() {
5764

58-
drummer = repository.save(new Role("drummer"));
59-
guitarist = repository.save(new Role("guitarist"));
60-
singer = repository.save(new Role("singer"));
65+
drummer = roleRepository.save(new Role("drummer"));
66+
guitarist = roleRepository.save(new Role("guitarist"));
67+
singer = roleRepository.save(new Role("singer"));
6168
}
6269

6370
@AfterEach
6471
void clearUp() {
65-
repository.deleteAll();
72+
roleRepository.deleteAll();
6673
}
6774

6875
@Test // GH-2283
@@ -81,6 +88,39 @@ void queryByExampleWithNoPredicatesShouldHaveNoWhereClause() {
8188

8289
// then
8390
assertThat(predicate).isNull();
84-
assertThat(repository.findAll(example)).containsExactlyInAnyOrder(drummer, guitarist, singer);
91+
assertThat(roleRepository.findAll(example)).containsExactlyInAnyOrder(drummer, guitarist, singer);
92+
}
93+
94+
@Test // GH-3763
95+
void usesAnyMatchOnJoins() {
96+
97+
User manager = new User("mighty", "super user", "[email protected]");
98+
99+
userRepository.save(manager);
100+
101+
User dave = new User();
102+
dave.setFirstname("dave");
103+
dave.setLastname("matthews");
104+
dave.setEmailAddress("[email protected]");
105+
dave.addRole(singer);
106+
107+
User carter = new User();
108+
carter.setFirstname("carter");
109+
carter.setLastname("beaufort");
110+
carter.setEmailAddress("[email protected]");
111+
carter.addRole(drummer);
112+
carter.addRole(singer);
113+
carter.setManager(manager);
114+
115+
userRepository.saveAllAndFlush(List.of(dave, carter));
116+
117+
User probe = new User();
118+
probe.setLastname(dave.getLastname());
119+
probe.setManager(manager);
120+
121+
Example<User> example = Example.of(probe,
122+
ExampleMatcher.matchingAny().withIgnorePaths("id", "createdAt", "age", "active", "emailAddress",
123+
"secondaryEmailAddress", "colleagues", "address", "binaryData", "attributes", "dateOfBirth"));
124+
assertThat(userRepository.findAll(example)).containsExactly(dave, carter);
85125
}
86126
}

0 commit comments

Comments
 (0)