|
16 | 16 | package org.springframework.data.jpa.repository.support;
|
17 | 17 |
|
18 | 18 | import static java.util.Collections.singletonMap;
|
| 19 | +import static org.assertj.core.api.Assertions.assertThat; |
19 | 20 | import static org.assertj.core.api.Assertions.assertThatNoException;
|
20 | 21 | import static org.mockito.Mockito.any;
|
21 | 22 | import static org.mockito.Mockito.never;
|
|
31 | 32 | import jakarta.persistence.criteria.CriteriaBuilder;
|
32 | 33 | import jakarta.persistence.criteria.CriteriaQuery;
|
33 | 34 |
|
| 35 | +import java.lang.reflect.Method; |
| 36 | +import java.lang.reflect.Modifier; |
34 | 37 | import java.util.Arrays;
|
| 38 | +import java.util.List; |
35 | 39 | import java.util.Optional;
|
| 40 | +import java.util.stream.Stream; |
36 | 41 |
|
37 | 42 | import org.junit.jupiter.api.BeforeEach;
|
38 | 43 | import org.junit.jupiter.api.Test;
|
39 | 44 | import org.junit.jupiter.api.extension.ExtendWith;
|
| 45 | +import org.junit.jupiter.params.ParameterizedTest; |
| 46 | +import org.junit.jupiter.params.provider.MethodSource; |
40 | 47 | import org.mockito.Mock;
|
41 | 48 | import org.mockito.junit.jupiter.MockitoExtension;
|
42 | 49 | import org.mockito.junit.jupiter.MockitoSettings;
|
|
45 | 52 | import org.springframework.data.jpa.domain.sample.User;
|
46 | 53 | import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
|
47 | 54 | import org.springframework.data.repository.CrudRepository;
|
| 55 | +import org.springframework.transaction.annotation.Transactional; |
48 | 56 |
|
49 | 57 | /**
|
50 | 58 | * Unit tests for {@link SimpleJpaRepository}.
|
|
54 | 62 | * @author Mark Paluch
|
55 | 63 | * @author Jens Schauder
|
56 | 64 | * @author Greg Turnquist
|
| 65 | + * @author Yanming Zhou |
57 | 66 | */
|
58 | 67 | @ExtendWith(MockitoExtension.class)
|
59 | 68 | @MockitoSettings(strictness = Strictness.LENIENT)
|
@@ -216,4 +225,17 @@ void applyQueryHintsToCountQueriesForSpecificationPageables() {
|
216 | 225 |
|
217 | 226 | verify(metadata).getQueryHintsForCount();
|
218 | 227 | }
|
| 228 | + |
| 229 | + @ParameterizedTest // GH-3188 |
| 230 | + @MethodSource("modifyingMethods") |
| 231 | + void checkTransactionalAnnotation(Method method) { |
| 232 | + Transactional transactional = method.getAnnotation(Transactional.class); |
| 233 | + assertThat(transactional).as("Method [%s] should be annotated with @Transactional", method).isNotNull(); |
| 234 | + assertThat(transactional.readOnly()).as("Method [%s] should not be annotated with @Transactional(readOnly = true)", method).isFalse(); |
| 235 | + } |
| 236 | + |
| 237 | + static List<Method> modifyingMethods() { |
| 238 | + return Stream.of(SimpleJpaRepository.class.getDeclaredMethods()).filter(method -> Modifier.isPublic(method.getModifiers()) && |
| 239 | + !method.isBridge() && (method.getName().startsWith("delete") || method.getName().startsWith("save"))).toList(); |
| 240 | + } |
219 | 241 | }
|
0 commit comments