|
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;
|
| 21 | +import static org.assertj.core.api.Assertions.fail; |
20 | 22 | import static org.mockito.Mockito.any;
|
21 | 23 | import static org.mockito.Mockito.never;
|
22 | 24 | import static org.mockito.Mockito.verify;
|
|
31 | 33 | import jakarta.persistence.criteria.CriteriaBuilder;
|
32 | 34 | import jakarta.persistence.criteria.CriteriaQuery;
|
33 | 35 |
|
| 36 | +import java.lang.reflect.Method; |
| 37 | +import java.lang.reflect.Modifier; |
34 | 38 | import java.util.Arrays;
|
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;
|
|
45 | 50 | import org.springframework.data.jpa.domain.sample.User;
|
46 | 51 | import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
|
47 | 52 | import org.springframework.data.repository.CrudRepository;
|
| 53 | +import org.springframework.transaction.annotation.Transactional; |
48 | 54 |
|
49 | 55 | /**
|
50 | 56 | * Unit tests for {@link SimpleJpaRepository}.
|
|
54 | 60 | * @author Mark Paluch
|
55 | 61 | * @author Jens Schauder
|
56 | 62 | * @author Greg Turnquist
|
| 63 | + * @author Yanming Zhou |
57 | 64 | */
|
58 | 65 | @ExtendWith(MockitoExtension.class)
|
59 | 66 | @MockitoSettings(strictness = Strictness.LENIENT)
|
@@ -216,4 +223,20 @@ void applyQueryHintsToCountQueriesForSpecificationPageables() {
|
216 | 223 |
|
217 | 224 | verify(metadata).getQueryHintsForCount();
|
218 | 225 | }
|
| 226 | + |
| 227 | + @Test // GH-3188 |
| 228 | + void checkTransactionalAnnotation() { |
| 229 | + Stream.of(SimpleJpaRepository.class.getDeclaredMethods()).filter(method -> Modifier.isPublic(method.getModifiers()) && |
| 230 | + (method.getName().startsWith("delete") || method.getName().startsWith("save"))).forEach( |
| 231 | + method -> { |
| 232 | + if (!method.isAnnotationPresent(Transactional.class)) { |
| 233 | + fail("Method [" + method + "] should be annotated with @Transactional"); |
| 234 | + } |
| 235 | + Transactional transactional = method.getAnnotation(Transactional.class); |
| 236 | + if (transactional.readOnly()) { |
| 237 | + fail("Method [" + method + "] should not be annotated with @Transactional(readOnly = true)"); |
| 238 | + } |
| 239 | + } |
| 240 | + ); |
| 241 | + } |
219 | 242 | }
|
0 commit comments