Polishing.

Fix merge problems.

Execute tests only for HsqlDb.

Refactoring to use lists instead of streams.
We try to avoid the latter, since they are prone to cause performance issues.

Minor refactorings.

See #771
See #230
Original pull request #1486
This commit is contained in:
Jens Schauder
2024-12-17 14:37:52 +01:00
parent 1515a3af42
commit 73d6788067
8 changed files with 299 additions and 273 deletions

View File

@@ -46,9 +46,11 @@ import org.springframework.test.jdbc.JdbcTestUtils;
* Very simple use cases for creation and usage of JdbcRepositories with test {@link Embedded} annotation in Entities.
*
* @author Bastian Wilhelm
* @author Yunyoung LEE
* @author Nikita Konev
*/
@IntegrationTest
public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
@Configuration
@Import(TestConfiguration.class)
@@ -66,7 +68,7 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
@Autowired Dialect dialect;
@Test // DATAJDBC-111
public void savesAnEntity() throws SQLException {
void savesAnEntity() throws SQLException {
DummyEntity entity = repository.save(createDummyEntity());
@@ -83,7 +85,7 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
@Test // DATAJDBC-111
public void saveAndLoadAnEntity() {
void saveAndLoadAnEntity() {
DummyEntity entity = repository.save(createDummyEntity());
@@ -99,7 +101,7 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
@Test // DATAJDBC-111
public void findAllFindsAllEntities() {
void findAllFindsAllEntities() {
DummyEntity entity = repository.save(createDummyEntity());
DummyEntity other = repository.save(createDummyEntity());
@@ -112,14 +114,14 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
@Test // DATAJDBC-111
public void findByIdReturnsEmptyWhenNoneFound() {
void findByIdReturnsEmptyWhenNoneFound() {
// NOT saving anything, so DB is empty
assertThat(repository.findById(-1L)).isEmpty();
}
@Test // DATAJDBC-111
public void update() {
void update() {
DummyEntity entity = repository.save(createDummyEntity());
@@ -139,7 +141,7 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
@Test // DATAJDBC-111
public void updateMany() {
void updateMany() {
DummyEntity entity = repository.save(createDummyEntity());
DummyEntity other = repository.save(createDummyEntity());
@@ -163,7 +165,7 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
@Test // DATAJDBC-111
public void deleteById() {
void deleteById() {
DummyEntity one = repository.save(createDummyEntity());
DummyEntity two = repository.save(createDummyEntity());
@@ -177,7 +179,7 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
@Test // DATAJDBC-111
public void deleteByEntity() {
void deleteByEntity() {
DummyEntity one = repository.save(createDummyEntity());
DummyEntity two = repository.save(createDummyEntity());
DummyEntity three = repository.save(createDummyEntity());
@@ -190,7 +192,7 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
@Test // DATAJDBC-111
public void deleteByList() {
void deleteByList() {
DummyEntity one = repository.save(createDummyEntity());
DummyEntity two = repository.save(createDummyEntity());
@@ -204,7 +206,7 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
@Test // DATAJDBC-111
public void deleteAll() {
void deleteAll() {
repository.save(createDummyEntity());
repository.save(createDummyEntity());
@@ -217,52 +219,53 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
assertThat(repository.findAll()).isEmpty();
}
@Test // DATAJDBC-551
public void deleteByTest() {
@Test // GH-771
void deleteBy() {
DummyEntity one = repository.save(createDummyEntity("root1"));
DummyEntity two = repository.save(createDummyEntity("root2"));
DummyEntity three = repository.save(createDummyEntity("root3"));
DummyEntity one = repository.save(createDummyEntity("root1"));
DummyEntity two = repository.save(createDummyEntity("root2"));
DummyEntity three = repository.save(createDummyEntity("root3"));
assertThat(repository.deleteByTest(two.getTest())).isEqualTo(1);
assertThat(repository.deleteByTest(two.getTest())).isEqualTo(1);
assertThat(repository.findAll()) //
.extracting(DummyEntity::getId) //
.containsExactlyInAnyOrder(one.getId(), three.getId());
assertThat(repository.findAll()) //
.extracting(DummyEntity::getId) //
.containsExactlyInAnyOrder(one.getId(), three.getId());
Long count = template.queryForObject("select count(1) from dummy_entity2", Collections.emptyMap(), Long.class);
assertThat(count).isEqualTo(4);
Long count = template.queryForObject("select count(1) from dummy_entity2", Collections.emptyMap(), Long.class);
assertThat(count).isEqualTo(4);
}
}
private static DummyEntity createDummyEntity() {
return createDummyEntity("root");
}
private static DummyEntity createDummyEntity() {
return createDummyEntity("root");
}
private static DummyEntity createDummyEntity(String test) {
DummyEntity entity = new DummyEntity();
entity.setTest(test);
private static DummyEntity createDummyEntity(String test) {
final Embeddable embeddable = new Embeddable();
embeddable.setTest("embedded");
DummyEntity entity = new DummyEntity();
entity.setTest(test);
final DummyEntity2 dummyEntity21 = new DummyEntity2();
dummyEntity21.setTest("entity1");
final Embeddable embeddable = new Embeddable();
embeddable.setTest("embedded");
final DummyEntity2 dummyEntity22 = new DummyEntity2();
dummyEntity22.setTest("entity2");
final DummyEntity2 dummyEntity21 = new DummyEntity2();
dummyEntity21.setTest("entity1");
embeddable.getList().add(dummyEntity21);
embeddable.getList().add(dummyEntity22);
final DummyEntity2 dummyEntity22 = new DummyEntity2();
dummyEntity22.setTest("entity2");
entity.setEmbeddable(embeddable);
embeddable.getList().add(dummyEntity21);
embeddable.getList().add(dummyEntity22);
return entity;
}
entity.setEmbeddable(embeddable);
return entity;
}
interface DummyEntityRepository extends CrudRepository<DummyEntity, Long> {
int deleteByTest(String test);
}
int deleteByTest(String test);
}
private static class DummyEntity {
@Column("ID")
@@ -298,8 +301,7 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
private static class Embeddable {
@MappedCollection(idColumn = "DUMMY_ID", keyColumn = "ORDER_KEY")
List<DummyEntity2> list = new ArrayList<>();
@MappedCollection(idColumn = "DUMMY_ID", keyColumn = "ORDER_KEY") List<DummyEntity2> list = new ArrayList<>();
String test;

View File

@@ -0,0 +1,121 @@
package org.springframework.data.jdbc.repository;
import static org.assertj.core.api.Assertions.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.jdbc.testing.DatabaseType;
import org.springframework.data.jdbc.testing.EnabledOnDatabase;
import org.springframework.data.jdbc.testing.IntegrationTest;
import org.springframework.data.jdbc.testing.TestConfiguration;
import org.springframework.data.repository.CrudRepository;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
/**
* Integration tests with collections chain.
*
* @author Yunyoung LEE
* @author Nikita Konev
*/
@IntegrationTest
@EnabledOnDatabase(DatabaseType.HSQL)
class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests {
@Autowired NamedParameterJdbcTemplate template;
@Autowired DummyEntityRepository repository;
private static DummyEntity createDummyEntity() {
DummyEntity entity = new DummyEntity();
entity.name = "Entity Name";
return entity;
}
@Test // DATAJDBC-551
void deleteByName() {
ChildElement element1 = createChildElement("one");
ChildElement element2 = createChildElement("two");
DummyEntity entity = createDummyEntity();
entity.content.add(element1);
entity.content.add(element2);
entity = repository.save(entity);
assertThat(repository.deleteByName("Entity Name")).isEqualTo(1);
assertThat(repository.findById(entity.id)).isEmpty();
Long count = template.queryForObject("select count(1) from grand_child_element", new HashMap<>(), Long.class);
assertThat(count).isEqualTo(0);
}
private ChildElement createChildElement(String name) {
ChildElement element = new ChildElement();
element.name = name;
element.content.add(createGrandChildElement(name + "1"));
element.content.add(createGrandChildElement(name + "2"));
return element;
}
private GrandChildElement createGrandChildElement(String content) {
GrandChildElement element = new GrandChildElement();
element.content = content;
return element;
}
interface DummyEntityRepository extends CrudRepository<DummyEntity, Long> {
long deleteByName(String name);
}
@Configuration
@Import(TestConfiguration.class)
static class Config {
@Autowired JdbcRepositoryFactory factory;
@Bean
Class<?> testClass() {
return JdbcRepositoryWithCollectionsChainHsqlIntegrationTests.class;
}
@Bean
DummyEntityRepository dummyEntityRepository() {
return factory.getRepository(DummyEntityRepository.class);
}
}
static class DummyEntity {
String name;
Set<ChildElement> content = new HashSet<>();
@Id private Long id;
}
static class ChildElement {
String name;
Set<GrandChildElement> content = new HashSet<>();
@Id private Long id;
}
static class GrandChildElement {
String content;
@Id private Long id;
}
}

View File

@@ -1,132 +0,0 @@
package org.springframework.data.jdbc.repository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.jdbc.testing.AssumeFeatureTestExecutionListener;
import org.springframework.data.jdbc.testing.TestConfiguration;
import org.springframework.data.repository.CrudRepository;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
/**
* Integration tests with collections chain.
*
* @author Yunyoung LEE
*/
@ContextConfiguration
@Transactional
@TestExecutionListeners(value = AssumeFeatureTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS)
@ExtendWith(SpringExtension.class)
public class JdbcRepositoryWithCollectionsChainIntegrationTests {
@Autowired NamedParameterJdbcTemplate template;
@Autowired DummyEntityRepository repository;
private static DummyEntity createDummyEntity() {
DummyEntity entity = new DummyEntity();
entity.setName("Entity Name");
return entity;
}
@Test // DATAJDBC-551
public void deleteByName() {
ChildElement element1 = createChildElement("one");
ChildElement element2 = createChildElement("two");
DummyEntity entity = createDummyEntity();
entity.content.add(element1);
entity.content.add(element2);
entity = repository.save(entity);
assertThat(repository.deleteByName("Entity Name")).isEqualTo(1);
assertThat(repository.findById(entity.id)).isEmpty();
Long count = template.queryForObject("select count(1) from grand_child_element", new HashMap<>(), Long.class);
assertThat(count).isEqualTo(0);
}
private ChildElement createChildElement(String name) {
ChildElement element = new ChildElement();
element.name = name;
element.content.add(createGrandChildElement(name + "1"));
element.content.add(createGrandChildElement(name + "2"));
return element;
}
private GrandChildElement createGrandChildElement(String content) {
GrandChildElement element = new GrandChildElement();
element.content = content;
return element;
}
interface DummyEntityRepository extends CrudRepository<DummyEntity, Long> {
long deleteByName(String name);
}
@Configuration
@Import(TestConfiguration.class)
static class Config {
@Autowired JdbcRepositoryFactory factory;
@Bean
Class<?> testClass() {
return JdbcRepositoryWithCollectionsChainIntegrationTests.class;
}
@Bean
DummyEntityRepository dummyEntityRepository() {
return factory.getRepository(DummyEntityRepository.class);
}
}
@Data
static class DummyEntity {
String name;
Set<ChildElement> content = new HashSet<>();
@Id private Long id;
}
@RequiredArgsConstructor
static class ChildElement {
String name;
Set<GrandChildElement> content = new HashSet<>();
@Id private Long id;
}
@RequiredArgsConstructor
static class GrandChildElement {
String content;
@Id private Long id;
}
}

View File

@@ -42,9 +42,11 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
*
* @author Jens Schauder
* @author Thomas Lang
* @author Yunyoung LEE
* @author Nikita Konev
*/
@IntegrationTest
public class JdbcRepositoryWithCollectionsIntegrationTests {
class JdbcRepositoryWithCollectionsIntegrationTests {
@Autowired NamedParameterJdbcTemplate template;
@Autowired DummyEntityRepository repository;
@@ -57,7 +59,7 @@ public class JdbcRepositoryWithCollectionsIntegrationTests {
}
@Test // DATAJDBC-113
public void saveAndLoadEmptySet() {
void saveAndLoadEmptySet() {
DummyEntity entity = repository.save(createDummyEntity());
@@ -71,7 +73,7 @@ public class JdbcRepositoryWithCollectionsIntegrationTests {
}
@Test // DATAJDBC-113
public void saveAndLoadNonEmptySet() {
void saveAndLoadNonEmptySet() {
Element element1 = new Element();
Element element2 = new Element();
@@ -94,7 +96,7 @@ public class JdbcRepositoryWithCollectionsIntegrationTests {
}
@Test // DATAJDBC-113
public void findAllLoadsCollection() {
void findAllLoadsCollection() {
Element element1 = new Element();
Element element2 = new Element();
@@ -117,7 +119,7 @@ public class JdbcRepositoryWithCollectionsIntegrationTests {
@Test // DATAJDBC-113
@EnabledOnFeature(SUPPORTS_GENERATED_IDS_IN_REFERENCED_ENTITIES)
public void updateSet() {
void updateSet() {
Element element1 = createElement("one");
Element element2 = createElement("two");
@@ -154,7 +156,7 @@ public class JdbcRepositoryWithCollectionsIntegrationTests {
}
@Test // DATAJDBC-113
public void deletingWithSet() {
void deletingWithSet() {
Element element1 = createElement("one");
Element element2 = createElement("two");
@@ -173,8 +175,8 @@ public class JdbcRepositoryWithCollectionsIntegrationTests {
assertThat(count).isEqualTo(0);
}
@Test // DATAJDBC-551
public void deleteByName() {
@Test // GH-771
void deleteByName() {
Element element1 = createElement("one");
Element element2 = createElement("two");

View File

@@ -0,0 +1,17 @@
CREATE TABLE DUMMY_ENTITY
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
NAME VARCHAR(100)
);
CREATE TABLE CHILD_ELEMENT
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
NAME VARCHAR(100),
DUMMY_ENTITY BIGINT
);
CREATE TABLE GRAND_CHILD_ELEMENT
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
CONTENT VARCHAR(100),
CHILD_ELEMENT BIGINT
);

View File

@@ -1,3 +0,0 @@
CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100));
CREATE TABLE child_element (id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, NAME VARCHAR(100), dummy_entity BIGINT);
CREATE TABLE grand_child_element (id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, CONTENT VARCHAR(100), child_element BIGINT);