Merge branch 'eugenp:master' into JAVA-20167_1

This commit is contained in:
timis1
2023-06-12 01:52:08 +03:00
committed by GitHub
304 changed files with 3868 additions and 750 deletions
@@ -8,10 +8,10 @@
<name>blaze-persistence</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<dependencyManagement>
@@ -42,7 +42,7 @@
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-integration-hibernate-5.4</artifactId>
<artifactId>blaze-persistence-integration-hibernate-5.6</artifactId>
</dependency>
<!-- Entity View dependencies -->
<dependency>
@@ -64,7 +64,7 @@
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-integration-spring-data-2.4</artifactId>
<artifactId>blaze-persistence-integration-spring-data-2.7</artifactId>
</dependency>
<!-- Spring dependencies -->
<dependency>
@@ -81,8 +81,8 @@
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
@@ -6,4 +6,5 @@ spring.datasource.url=jdbc:h2:mem:test
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.defer-datasource-initialization=true
@@ -1,21 +1,19 @@
package com.baeldung;
import com.baeldung.model.Person;
import com.baeldung.model.Post;
import com.baeldung.repository.PersonRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@ContextConfiguration(classes = TestContextConfig.class)
@ExtendWith(SpringExtension.class)
import com.baeldung.model.Person;
import com.baeldung.model.Post;
import com.baeldung.repository.PersonRepository;
@SpringBootTest
public class PersonUnitTest {
@Autowired
@@ -1,23 +1,21 @@
package com.baeldung;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.baeldung.model.Post;
import com.baeldung.repository.PostRepository;
import com.baeldung.repository.PostViewRepository;
import com.baeldung.view.PostView;
import com.baeldung.view.PostWithAuthorView;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ContextConfiguration(classes = TestContextConfig.class)
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class PostUnitTest {
@Autowired
@@ -36,8 +34,7 @@ public class PostUnitTest {
@Test
public void givenPostIdAndAuthorName_whenFind_thenReturnCorrectResult() {
final Iterable<PostWithAuthorView> listIterable =
postRepository.findBy("Spring", "Peter");
final Iterable<PostWithAuthorView> listIterable = postRepository.findBy("Spring", "Peter");
final List<PostView> list = new ArrayList<>();
listIterable.forEach(list::add);
assertEquals(4, list.size());
@@ -50,5 +47,4 @@ public class PostUnitTest {
listIterable.forEach(list::add);
assertEquals(7, list.size());
}
}
@@ -1,15 +0,0 @@
package com.baeldung;
import com.blazebit.persistence.integration.view.spring.EnableEntityViews;
import com.blazebit.persistence.spring.data.repository.config.EnableBlazeRepositories;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.baeldung")
@EnableEntityViews(basePackages = {"com.baeldung.view"})
@EnableBlazeRepositories(basePackages = "com.baeldung.repository")
public class TestContextConfig {
}
@@ -10,6 +10,16 @@ public class Address {
private String country;
private int zipCode;
public Address(String addressLine1, String addressLine2, String city, String country, int zipCode) {
this.addressLine1 = addressLine1;
this.addressLine2 = addressLine2;
this.city = city;
this.country = country;
this.zipCode = zipCode;
}
public Address() {}
public String getAddressLine1() {
return addressLine1;
}
@@ -2,19 +2,13 @@ package com.baeldung.hibernate.customtypes;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.spi.ValueAccess;
import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
public class AddressType implements CompositeUserType<Address>, UserType<Address> {
public class AddressType implements CompositeUserType<Address> {
@Override
public Object getPropertyValue(Address component, int property) throws HibernateException {
@@ -39,7 +33,8 @@ public class AddressType implements CompositeUserType<Address>, UserType<Address
@Override
public Address instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) {
return null;
return new Address(values.getValue(0, String.class), values.getValue(1,String.class), values.getValue(2, String.class),
values.getValue(3, String.class), values.getValue(4,Integer.class));
}
@Override
@@ -47,11 +42,6 @@ public class AddressType implements CompositeUserType<Address>, UserType<Address
return Address.class;
}
@Override
public int getSqlType() {
return Types.VARCHAR;
}
@Override
public Class<Address> returnedClass() {
return Address.class;
@@ -73,36 +63,6 @@ public class AddressType implements CompositeUserType<Address>, UserType<Address
return x.hashCode();
}
@Override
public Address nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
Address empAdd = new Address();
empAdd.setAddressLine1(rs.getString(position));
if (rs.wasNull())
return null;
empAdd.setAddressLine2(rs.getString(position));
empAdd.setCity(rs.getString(position));
empAdd.setCountry(rs.getString(position));
empAdd.setZipCode(rs.getInt(position));
return empAdd;
}
@Override
public void nullSafeSet(PreparedStatement st, Address value, int index, SharedSessionContractImplementor session) throws SQLException {
if (Objects.isNull(value))
st.setNull(index, Types.VARCHAR);
else {
st.setString(index, value.getAddressLine1());
st.setString(index + 1, value.getAddressLine2());
st.setString(index + 2, value.getCity());
st.setString(index + 3, value.getCountry());
st.setInt(index + 4, value.getZipCode());
}
}
@Override
public Address deepCopy(Address value) {
if (Objects.isNull(value))
@@ -34,7 +34,7 @@ public class OfficeEmployee {
@AttributeOverride(name = "cityCode", column = @Column(name = "city_code")),
@AttributeOverride(name = "number", column = @Column(name = "number"))
})
@Type(value = PhoneNumberType.class)
@CompositeType(value = PhoneNumberType.class)
private PhoneNumber employeeNumber;
@CompositeType(value = com.baeldung.hibernate.customtypes.AddressType.class)
@@ -49,10 +49,6 @@ public class OfficeEmployee {
@Type(value = com.baeldung.hibernate.customtypes.SalaryType.class,
parameters = {@Parameter(name = "currency", value = "USD")})
@AttributeOverrides({
@AttributeOverride(name = "amount", column = @Column(name = "amount")),
@AttributeOverride(name = "currency", column = @Column(name = "currency"))
})
private Salary salary;
public Salary getSalary() {
@@ -1,20 +1,37 @@
package com.baeldung.hibernate.customtypes;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.spi.ValueAccess;
import org.hibernate.usertype.CompositeUserType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
public class PhoneNumberType implements UserType<PhoneNumber> {
public class PhoneNumberType implements CompositeUserType<PhoneNumber> {
@Override
public int getSqlType() {
return Types.INTEGER;
public Object getPropertyValue(PhoneNumber component, int property) throws HibernateException {
switch (property) {
case 0:
return component.getCountryCode();
case 1:
return component.getCityCode();
case 2:
return component.getNumber();
default:
throw new IllegalArgumentException(property + " is an invalid property index for class type " + component.getClass().getName());
}
}
@Override
public PhoneNumber instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) {
return new PhoneNumber(values.getValue(0, Integer.class), values.getValue(1, Integer.class), values.getValue(2,Integer.class));
}
@Override
public Class<?> embeddable() {
return PhoneNumber.class;
}
@Override
@@ -37,32 +54,6 @@ public class PhoneNumberType implements UserType<PhoneNumber> {
return x.hashCode();
}
@Override
public PhoneNumber nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
int countryCode = rs.getInt(position);
if (rs.wasNull())
return null;
int cityCode = rs.getInt(position);
int number = rs.getInt(position);
return new PhoneNumber(countryCode, cityCode, number);
}
@Override
public void nullSafeSet(PreparedStatement st, PhoneNumber value, int index, SharedSessionContractImplementor session) throws SQLException {
if (Objects.isNull(value)) {
st.setNull(index, Types.INTEGER);
st.setNull(index+1, Types.INTEGER);
st.setNull(index+2, Types.INTEGER);
} else {
st.setInt(index, value.getCountryCode());
st.setInt(index+1, value.getCityCode());
st.setInt(index+2, value.getNumber());
}
}
@Override
public PhoneNumber deepCopy(PhoneNumber value) {
if (Objects.isNull(value))
@@ -1,8 +1,9 @@
package com.baeldung.hibernate.customtypes;
import java.io.Serializable;
import java.util.Objects;
public class Salary {
public class Salary implements Serializable {
private Long amount;
private String currency;
@@ -1,10 +1,6 @@
package com.baeldung.hibernate.customtypes;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.spi.ValueAccess;
import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.DynamicParameterizedType;
import org.hibernate.usertype.UserType;
@@ -16,38 +12,13 @@ import java.sql.Types;
import java.util.Objects;
import java.util.Properties;
public class SalaryType implements UserType<Salary>, CompositeUserType<Salary>, DynamicParameterizedType {
public class SalaryType implements UserType<Salary>, DynamicParameterizedType {
private String localCurrency;
@Override
public Object getPropertyValue(Salary component, int property) throws HibernateException {
switch (property) {
case 0:
return component.getAmount();
case 1:
return component.getCurrency();
default:
throw new IllegalArgumentException(property +
" is an invalid property index for class type " +
component.getClass().getName());
}
}
@Override
public Salary instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) {
return null;
}
@Override
public Class<?> embeddable() {
return Salary.class;
}
@Override
public int getSqlType() {
return Types.BIGINT;
return Types.VARCHAR;
}
@Override
@@ -74,12 +45,12 @@ public class SalaryType implements UserType<Salary>, CompositeUserType<Salary>,
@Override
public Salary nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
Salary salary = new Salary();
salary.setAmount(rs.getLong(position));
if (rs.wasNull())
return null;
String salaryValue = rs.getString(position);
salary.setCurrency(rs.getString(position));
salary.setAmount(Long.parseLong(salaryValue.split(" ")[1]));
salary.setCurrency(salaryValue.split(" ")[0]);
return salary;
}
@@ -87,13 +58,11 @@ public class SalaryType implements UserType<Salary>, CompositeUserType<Salary>,
@Override
public void nullSafeSet(PreparedStatement st, Salary value, int index, SharedSessionContractImplementor session) throws SQLException {
if (Objects.isNull(value))
st.setNull(index, Types.BIGINT);
st.setNull(index, Types.VARCHAR);
else {
st.setLong(index, SalaryCurrencyConvertor.convert(
value.getAmount(),
value.getCurrency(), localCurrency));
st.setString(index + 1, value.getCurrency());
Long salaryValue = SalaryCurrencyConvertor.convert(value.getAmount(),
value.getCurrency(), localCurrency);
st.setString(index, value.getCurrency() + " " + salaryValue);
}
}
@@ -117,7 +86,7 @@ public class SalaryType implements UserType<Salary>, CompositeUserType<Salary>,
@Override
public Serializable disassemble(Salary value) {
return (Serializable) deepCopy(value);
return deepCopy(value);
}
@Override
@@ -11,10 +11,12 @@ import org.junit.Test;
import jakarta.persistence.TypedQuery;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class HibernateCustomTypesIntegrationTest {
@@ -74,12 +76,18 @@ public class HibernateCustomTypesIntegrationTest {
doInHibernate(this::sessionFactory, session -> {
session.save(e);
session.flush();
session.refresh(e);
TypedQuery<OfficeEmployee> query = session.createQuery("FROM OfficeEmployee OE WHERE OE.empAddress.zipCode = :pinCode", OfficeEmployee.class);
query.setParameter("pinCode",100);
int size = query.getResultList().size();
final List<OfficeEmployee> resultList = query.getResultList();
int size = resultList.size();
assertEquals(1, size);
assertNotNull(resultList.get(0).getEmployeeNumber());
assertNotNull(resultList.get(0).getEmpAddress());
assertNotNull(resultList.get(0).getSalary());
});
}
@@ -5,9 +5,9 @@ This module contains articles about enterprise concerns such as Multitenancy, Er
### Relevant articles:
- [Introduction to Hibernate Spatial](https://www.baeldung.com/hibernate-spatial)
- [A Guide to Multitenancy in Hibernate 5](https://www.baeldung.com/hibernate-5-multitenancy)
- [A Guide to Multitenancy in Hibernate 6](https://www.baeldung.com/hibernate-6-multitenancy)
- [Hibernate Aggregate Functions](https://www.baeldung.com/hibernate-aggregate-functions)
- [Common Hibernate Exceptions](https://www.baeldung.com/hibernate-exceptions)
- [Hibernate Error “Not all named parameters have been set”](https://www.baeldung.com/hibernate-error-named-parameters-not-set)
- [Various Logging Levels in Hibernate](https://www.baeldung.com/hibernate-logging-levels)
- [Hibernate: save, persist, update, merge, saveOrUpdate](https://www.baeldung.com/hibernate-save-persist-update-merge-saveorupdate)
- [Hibernate: save, persist, update, merge, saveOrUpdate](https://www.baeldung.com/hibernate-save-persist-update-merge-saveorupdate)
@@ -7,3 +7,4 @@ This module contains articles about Hibernate Mappings.
- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many)
- [Boolean Converters in Hibernate 6](https://www.baeldung.com/java-hibernate-6-boolean-converters)
- [Generate UUIDs as Primary Keys With Hibernate](https://www.baeldung.com/java-hibernate-uuid-primary-key)
- [Understanding JPA/Hibernate Associations](https://www.baeldung.com/jpa-hibernate-associations)
+6
View File
@@ -69,6 +69,11 @@
<artifactId>javax.annotation-api</artifactId>
<version>${javax.annotation.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
<build>
@@ -130,6 +135,7 @@
<h2.version>2.1.214</h2.version>
<jakarta.xml.bind-api.version>4.0.0</jakarta.xml.bind-api.version>
<javax.annotation.version>1.3.2</javax.annotation.version>
<mysql.version>8.0.33</mysql.version>
</properties>
</project>
@@ -25,7 +25,7 @@ public class PersonDaoIntegrationTest {
//
@Test
public void testCreation() {
public void givenExistingPersons_whenFindingPersonByFirstName_thenFound() {
personDao.save(new Person("Erich", "Gamma"));
final Person person = new Person("Kent", "Beck");
personDao.save(person);
@@ -36,7 +36,7 @@ public class PersonDaoIntegrationTest {
}
@Test
public void testMultipleFilter() {
public void givenExistingPersons_whenFindingPersonByFirstNameAndSurName_thenFound() {
personDao.save(new Person("Erich", "Gamma"));
final Person person = personDao.save(new Person("Ralph", "Beck"));
final Person person2 = personDao.save(new Person("Ralph", "Johnson"));
@@ -47,7 +47,7 @@ public class PersonDaoIntegrationTest {
}
@Test
public void testOrdering() {
public void givenExistingPersons_whenFindingPersonByFirstNameInDescendingOrder_thenFound() {
final Person person = personDao.save(new Person("Kent", "Gamma"));
personDao.save(new Person("Ralph", "Johnson"));
final Person person2 = personDao.save(new Person("Kent", "Zivago"));
@@ -58,7 +58,7 @@ public class PersonDaoIntegrationTest {
}
@Test
public void testMaxAge() {
public void givenExistingPersons_whenFindingMaxAge_thenFound() {
personDao.save(new Person("Kent", "Gamma", 20));
personDao.save(new Person("Ralph", "Johnson", 35));
personDao.save(new Person("Kent", "Zivago", 30));
@@ -68,7 +68,7 @@ public class PersonDaoIntegrationTest {
}
@Test
public void testMaxAgeByName() {
public void givenExistingPersons_whenFindingMaxAgeByName_thenFound() {
personDao.save(new Person("Kent", "Gamma", 20));
personDao.save(new Person("Ralph", "Johnson", 35));
personDao.save(new Person("Kent", "Zivago", 30));
@@ -38,7 +38,7 @@ public class JedisIntegrationTest {
redisServer = RedisServer.builder()
.port(port)
.setting("maxheap 128M")
.setting("maxmemory 128M")
.build();
redisServer.start();
@@ -34,7 +34,7 @@ public class RedissonConfigurationIntegrationTest {
redisServer = RedisServer.builder()
.port(port)
.setting("maxheap 128M")
.setting("maxmemory 128M")
.build();
redisServer.start();
}
@@ -32,7 +32,7 @@ public class RedissonIntegrationTest {
public static void setUp() {
redisServer = RedisServer.builder()
.port(6379)
.setting("maxheap 128M")
.setting("maxmemory 128M")
.build();
redisServer.start();
client = Redisson.create();
@@ -25,7 +25,7 @@ public class DeleteEverythingInRedisIntegrationTest {
redisServer = RedisServer.builder()
.port(port)
.setting("maxheap 128M")
.setting("maxmemory 128M")
.build();
redisServer.start();
@@ -27,7 +27,7 @@ public class NaiveApproachIntegrationTest {
redisServer = RedisServer.builder()
.port(port)
.setting("maxheap 128M")
.setting("maxmemory 128M")
.build();
}
@@ -33,7 +33,7 @@ public class ScanStrategyIntegrationTest {
redisServer = RedisServer.builder()
.port(port)
.setting("maxheap 128M")
.setting("maxmemory 128M")
.build();
}
@@ -5,7 +5,7 @@ This module contains articles about annotations used in Spring Data JPA
### Relevant articles
- [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd)
- [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable)
- [Jpa @Embedded and @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable)
- [Spring JPA @Embedded and @EmbeddedId](https://www.baeldung.com/spring-jpa-embedded-method-parameters)
- [Programmatic Transaction Management in Spring](https://www.baeldung.com/spring-programmatic-transaction-management)
- [JPA Entity Lifecycle Events](https://www.baeldung.com/jpa-entity-lifecycle-events)
@@ -6,7 +6,7 @@ This module contains articles about Spring Data JPA used in enterprise applicati
- [Spring Data Java 8 Support](https://www.baeldung.com/spring-data-java-8)
- [DB Integration Tests with Spring Boot and Testcontainers](https://www.baeldung.com/spring-boot-testcontainers-integration-test)
- [A Guide to Springs Open Session In View](https://www.baeldung.com/spring-open-session-in-view)
- [A Guide to Springs Open Session in View](https://www.baeldung.com/spring-open-session-in-view)
- [Working with Lazy Element Collections in JPA](https://www.baeldung.com/java-jpa-lazy-collections)
- [Custom Naming Convention with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-custom-naming)
- [Partial Data Update With Spring Data](https://www.baeldung.com/spring-data-partial-update)
@@ -9,7 +9,7 @@ This module contains articles about querying data using Spring Data JPA .
- [Hibernate Pagination](https://www.baeldung.com/hibernate-pagination)
- [Sorting with Hibernate](https://www.baeldung.com/hibernate-sort)
- [Stored Procedures with Hibernate](https://www.baeldung.com/stored-procedures-with-hibernate-tutorial)
- [Eager/Lazy Loading In Hibernate](https://www.baeldung.com/hibernate-lazy-eager-loading)
- [Eager/Lazy Loading in Hibernate](https://www.baeldung.com/hibernate-lazy-eager-loading)
- [Auditing with JPA, Hibernate, and Spring Data JPA](https://www.baeldung.com/database-auditing-jpa)
- More articles: [[<-- prev]](../spring-data-jpa-query)[[more -->]](../spring-data-jpa-query-3)
@@ -10,4 +10,5 @@
- [Differences Between Spring Data JPA findFirst() and findTop()](https://www.baeldung.com/spring-data-jpa-findfirst-vs-findtop)
- [Difference Between findBy and findAllBy in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-find-by-vs-find-all-by)
- [Unidirectional One-to-Many and Cascading Delete in JPA](https://www.baeldung.com/spring-jpa-unidirectional-one-to-many-and-cascading-delete)
- [TRUNCATE TABLE in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-truncate-table)
- More articles: [[<-- prev]](../spring-data-jpa-repo)
@@ -6,4 +6,5 @@ This module contains articles about Spring Data JPA.
- [New CRUD Repository Interfaces in Spring Data 3](https://www.baeldung.com/spring-data-3-crud-repository-interfaces)
- [How to Persist a List of String in JPA?](https://www.baeldung.com/java-jpa-persist-string-list)
- [Hibernate Natural IDs in Spring Boot](https://www.baeldung.com/spring-boot-hibernate-natural-ids)
- [Correct Use of flush() in JPA](https://www.baeldung.com/spring-jpa-flush)
- More articles: [[<-- prev]](../spring-data-jpa-repo-2)
@@ -10,7 +10,6 @@ This module contains articles about repositories in Spring Data JPA
- [Spring Data Composable Repositories](https://www.baeldung.com/spring-data-composable-repositories)
- [Spring Data JPA Repository Populators](https://www.baeldung.com/spring-data-jpa-repository-populators)
- [Calling Stored Procedures from Spring Data JPA Repositories](https://www.baeldung.com/spring-data-jpa-stored-procedures)
- [TRUNCATE TABLE in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-truncate-table)
- More articles: [[--> next]](../spring-data-jpa-repo-2)
### Eclipse Config