|
15 | 15 | */
|
16 | 16 | package org.springframework.data.jdbc.repository;
|
17 | 17 |
|
18 |
| -import static java.util.Arrays.*; |
19 |
| -import static java.util.Collections.*; |
20 |
| -import static org.assertj.core.api.Assertions.*; |
21 |
| -import static org.assertj.core.api.SoftAssertions.*; |
| 18 | +import static java.util.Arrays.asList; |
| 19 | +import static java.util.Collections.emptyList; |
| 20 | +import static java.util.Collections.singletonList; |
| 21 | +import static org.assertj.core.api.Assertions.assertThat; |
| 22 | +import static org.assertj.core.api.Assertions.assertThatThrownBy; |
| 23 | +import static org.assertj.core.api.SoftAssertions.assertSoftly; |
22 | 24 |
|
23 | 25 | import java.io.IOException;
|
24 | 26 | import java.sql.ResultSet;
|
|
37 | 39 | import java.util.function.Consumer;
|
38 | 40 | import java.util.stream.Stream;
|
39 | 41 |
|
| 42 | +import org.assertj.core.api.Assertions; |
40 | 43 | import org.junit.jupiter.api.BeforeEach;
|
41 | 44 | import org.junit.jupiter.api.Test;
|
42 | 45 | import org.junit.jupiter.params.ParameterizedTest;
|
|
49 | 52 | import org.springframework.context.annotation.Configuration;
|
50 | 53 | import org.springframework.context.annotation.Import;
|
51 | 54 | import org.springframework.core.io.ClassPathResource;
|
| 55 | +import org.springframework.dao.DuplicateKeyException; |
52 | 56 | import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
53 | 57 | import org.springframework.data.annotation.Id;
|
54 |
| -import org.springframework.data.domain.*; |
| 58 | +import org.springframework.data.annotation.Transient; |
| 59 | +import org.springframework.data.domain.Example; |
| 60 | +import org.springframework.data.domain.ExampleMatcher; |
| 61 | +import org.springframework.data.domain.Limit; |
| 62 | +import org.springframework.data.domain.Page; |
| 63 | +import org.springframework.data.domain.PageRequest; |
| 64 | +import org.springframework.data.domain.Pageable; |
| 65 | +import org.springframework.data.domain.Persistable; |
| 66 | +import org.springframework.data.domain.ScrollPosition; |
| 67 | +import org.springframework.data.domain.Slice; |
| 68 | +import org.springframework.data.domain.Sort; |
| 69 | +import org.springframework.data.domain.Window; |
55 | 70 | import org.springframework.data.jdbc.core.mapping.AggregateReference;
|
56 | 71 | import org.springframework.data.jdbc.repository.query.Modifying;
|
57 | 72 | import org.springframework.data.jdbc.repository.query.Query;
|
|
64 | 79 | import org.springframework.data.jdbc.testing.TestDatabaseFeatures;
|
65 | 80 | import org.springframework.data.relational.core.mapping.Column;
|
66 | 81 | import org.springframework.data.relational.core.mapping.MappedCollection;
|
67 |
| -import org.springframework.data.relational.core.mapping.Table; |
68 | 82 | import org.springframework.data.relational.core.mapping.Sequence;
|
| 83 | +import org.springframework.data.relational.core.mapping.Table; |
69 | 84 | import org.springframework.data.relational.core.mapping.event.AbstractRelationalEvent;
|
70 | 85 | import org.springframework.data.relational.core.mapping.event.AfterConvertEvent;
|
71 | 86 | import org.springframework.data.relational.core.sql.LockMode;
|
@@ -104,6 +119,8 @@ public class JdbcRepositoryIntegrationTests {
|
104 | 119 |
|
105 | 120 | @Autowired NamedParameterJdbcTemplate template;
|
106 | 121 | @Autowired DummyEntityRepository repository;
|
| 122 | + |
| 123 | + @Autowired ProvidedIdEntityRepository providedIdEntityRepository; |
107 | 124 | @Autowired MyEventListener eventListener;
|
108 | 125 | @Autowired RootRepository rootRepository;
|
109 | 126 | @Autowired WithDelimitedColumnRepository withDelimitedColumnRepository;
|
@@ -208,6 +225,18 @@ public void findAllFindsAllSpecifiedEntities() {
|
208 | 225 | .containsExactlyInAnyOrder(entity.getIdProp(), other.getIdProp());
|
209 | 226 | }
|
210 | 227 |
|
| 228 | + @Test // DATAJDBC-611 |
| 229 | + public void testDuplicateKeyExceptionIsThrownInCaseOfUniqueKeyViolation() { |
| 230 | + |
| 231 | + // given. |
| 232 | + ProvidedIdEntity first = ProvidedIdEntity.newInstance(1L, "name"); |
| 233 | + ProvidedIdEntity second = ProvidedIdEntity.newInstance(1L, "other"); |
| 234 | + |
| 235 | + // when/then |
| 236 | + Assertions.assertThatCode(() -> providedIdEntityRepository.save(first)).doesNotThrowAnyException(); |
| 237 | + Assertions.assertThatThrownBy(() -> providedIdEntityRepository.save(second)).isInstanceOf(DuplicateKeyException.class); |
| 238 | + } |
| 239 | + |
211 | 240 | @Test // DATAJDBC-97
|
212 | 241 | public void countsEntities() {
|
213 | 242 |
|
@@ -1436,6 +1465,10 @@ interface DummyProjectExample {
|
1436 | 1465 | String getName();
|
1437 | 1466 | }
|
1438 | 1467 |
|
| 1468 | + interface ProvidedIdEntityRepository extends CrudRepository<ProvidedIdEntity, Long> { |
| 1469 | + |
| 1470 | + } |
| 1471 | + |
1439 | 1472 | interface DummyEntityRepository extends CrudRepository<DummyEntity, Long>, QueryByExampleExecutor<DummyEntity> {
|
1440 | 1473 |
|
1441 | 1474 | @Lock(LockMode.PESSIMISTIC_WRITE)
|
@@ -1543,6 +1576,11 @@ DummyEntityRepository dummyEntityRepository() {
|
1543 | 1576 | return factory.getRepository(DummyEntityRepository.class);
|
1544 | 1577 | }
|
1545 | 1578 |
|
| 1579 | + @Bean |
| 1580 | + ProvidedIdEntityRepository providedIdEntityRepository() { |
| 1581 | + return factory.getRepository(ProvidedIdEntityRepository.class); |
| 1582 | + } |
| 1583 | + |
1546 | 1584 | @Bean
|
1547 | 1585 | RootRepository rootRepository() {
|
1548 | 1586 | return factory.getRepository(RootRepository.class);
|
@@ -1886,6 +1924,37 @@ public String getName() {
|
1886 | 1924 | }
|
1887 | 1925 | }
|
1888 | 1926 |
|
| 1927 | + static class ProvidedIdEntity implements Persistable<Long> { |
| 1928 | + |
| 1929 | + @Id |
| 1930 | + private final Long id; |
| 1931 | + |
| 1932 | + private String name; |
| 1933 | + |
| 1934 | + @Transient |
| 1935 | + private boolean isNew; |
| 1936 | + |
| 1937 | + private ProvidedIdEntity(Long id, String name, boolean isNew) { |
| 1938 | + this.id = id; |
| 1939 | + this.name = name; |
| 1940 | + this.isNew = isNew; |
| 1941 | + } |
| 1942 | + |
| 1943 | + private static ProvidedIdEntity newInstance(Long id, String name) { |
| 1944 | + return new ProvidedIdEntity(id, name, true); |
| 1945 | + } |
| 1946 | + |
| 1947 | + @Override |
| 1948 | + public Long getId() { |
| 1949 | + return id; |
| 1950 | + } |
| 1951 | + |
| 1952 | + @Override |
| 1953 | + public boolean isNew() { |
| 1954 | + return isNew; |
| 1955 | + } |
| 1956 | + } |
| 1957 | + |
1889 | 1958 | static class DummyEntity {
|
1890 | 1959 |
|
1891 | 1960 | String name;
|
|
0 commit comments