Last active
March 27, 2025 03:06
-
-
Save ThomasVitale/7d127d56e3eb1a6f7b30990f1d5b7850 to your computer and use it in GitHub Desktop.
Spring Data JPA - Basic Configuration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.thomasvitale.jpa.demo; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
@SpringBootApplication | |
public class Application { | |
public static void main(String[] args) { | |
SpringApplication.run(Application.class, args); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) | |
# JDBC URL of the database. | |
spring.datasource.url=jdbc:postgresql://localhost:12345/app | |
# Login username of the database. | |
spring.datasource.username=username | |
# Login password of the database. | |
spring.datasource.password=password | |
# JPA (JpaBaseConfiguration, HibernateJpaAutoConfiguration) | |
# DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. Defaults to "create-drop" when using an embedded database and no schema manager was detected. Otherwise, defaults to "none". | |
spring.jpa.hibernate.ddl-auto=update | |
# Whether to enable logging of SQL statements. | |
spring.jpa.show-sql=true | |
# Hibernate additional native properties to set on the JPA provider. | |
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect | |
spring.jpa.properties.hibernate.current_session_context_class=thread | |
spring.jpa.properties.hibernate.format_sql=true | |
# Fix Postgres JPA Error (Method org.postgresql.jdbc.PgConnection.createClob() is not yet implemented). | |
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.thomasvitale.jpa.demo; | |
import com.thomasvitale.jpa.demo.model.Person; | |
import com.thomasvitale.jpa.demo.repository.PersonRepository; | |
import org.junit.After; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.junit.runner.RunWith; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.boot.test.context.SpringBootTest; | |
import org.springframework.test.context.junit4.SpringRunner; | |
import java.util.List; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertNull; | |
@RunWith(SpringRunner.class) | |
@SpringBootTest | |
public class ApplicationIntegrationTests { | |
@Autowired | |
private PersonRepository personRepository; | |
@Before | |
public void setUp() { | |
// Save 4 Person objects into the database | |
personRepository.save(new Person("Sheldon", "Cooper", "123456")); | |
personRepository.save(new Person("Missy", "Cooper", "234567")); | |
personRepository.save(new Person("Leonard", "Hofstadter", "345678")); | |
personRepository.save(new Person("Leonard", "Nimoy", "456789")); | |
} | |
@After | |
public void cleanUp() { | |
// Delete all test data | |
personRepository.deleteAll(); | |
} | |
@Test | |
public void testCRUD() { | |
// Create | |
Person originalPerson = new Person("Howard", "Wolowitz", "654321"); | |
personRepository.save(originalPerson); | |
Person createdPerson = personRepository.findBySsn("654321"); | |
assertEquals(originalPerson.getFirstName(), createdPerson.getFirstName()); | |
assertEquals(originalPerson.getLastName(), createdPerson.getLastName()); | |
assertEquals(originalPerson.getSsn(), createdPerson.getSsn()); | |
// Update | |
createdPerson.setFirstName("Fruit Loops"); | |
personRepository.save(createdPerson); | |
Person updatedPerson = personRepository.findBySsn("654321"); | |
assertEquals(createdPerson.getFirstName(), updatedPerson.getFirstName()); | |
// Delete | |
personRepository.delete(updatedPerson); | |
assertNull(personRepository.findBySsn("654321")); | |
} | |
@Test | |
public void testFindAll() { | |
// Get all the people | |
List<Person> people = personRepository.findAll(); | |
assertEquals(4, people.size()); | |
} | |
@Test | |
public void testFindByFirstName() { | |
// Get all the people with a specific first name | |
List<Person> people = personRepository.findByFirstName("Leonard"); | |
assertEquals(2, people.size()); | |
} | |
@Test | |
public void testFindByLastName() { | |
// Get all the people with a specific last name | |
List<Person> people = personRepository.findByLastName("Cooper"); | |
assertEquals(2, people.size()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
buildscript { | |
ext { | |
springBootVersion = '2.0.5.RELEASE' | |
} | |
repositories { | |
mavenCentral() | |
} | |
dependencies { | |
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") | |
} | |
} | |
apply plugin: 'java' | |
apply plugin: 'eclipse' | |
apply plugin: 'org.springframework.boot' | |
apply plugin: 'io.spring.dependency-management' | |
group = 'com.thomasvitale.jpa' | |
version = '0.0.1-SNAPSHOT' | |
sourceCompatibility = 1.8 | |
repositories { | |
mavenCentral() | |
} | |
dependencies { | |
implementation('org.springframework.boot:spring-boot-starter-data-jpa') | |
runtimeOnly('org.postgresql:postgresql') | |
testImplementation('org.springframework.boot:spring-boot-starter-test') | |
testRuntimeOnly('org.postgresql:postgresql') | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.thomasvitale.jpa.demo.config; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.core.env.Environment; | |
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; | |
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; | |
import org.springframework.jdbc.datasource.DriverManagerDataSource; | |
import org.springframework.orm.jpa.JpaTransactionManager; | |
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; | |
import org.springframework.orm.jpa.vendor.Database; | |
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; | |
import org.springframework.transaction.PlatformTransactionManager; | |
import org.springframework.transaction.annotation.EnableTransactionManagement; | |
import javax.persistence.EntityManagerFactory; | |
import javax.sql.DataSource; | |
import java.util.Properties; | |
// This configuration class is useless in the context of this example. | |
// I have included it here just for letting you know what it happens | |
// behind the scenes when we rely on the default configuration. | |
// It could be the starting point of a more advanced and customised configuration. | |
@Configuration | |
@EnableTransactionManagement | |
@EnableJpaRepositories(basePackages = "com.thomasvitale.jpa.demo.repository") | |
public class JpaConfig { | |
@Autowired | |
private Environment env; | |
@Bean | |
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { | |
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); | |
vendorAdapter.setDatabase(Database.POSTGRESQL); | |
vendorAdapter.setGenerateDdl(true); | |
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); | |
em.setDataSource(dataSource()); | |
em.setPackagesToScan("com.thomasvitale.jpa.demo.model"); | |
em.setJpaVendorAdapter(vendorAdapter); | |
em.setJpaProperties(additionalProperties()); | |
return em; | |
} | |
@Bean | |
public DataSource dataSource() { | |
DriverManagerDataSource dataSource = new DriverManagerDataSource(); | |
dataSource.setDriverClassName("org.postgresql.Driver"); | |
dataSource.setUrl(env.getProperty("spring.datasource.url")); | |
dataSource.setUsername(env.getProperty("spring.datasource.username")); | |
dataSource.setPassword(env.getProperty("spring.datasource.password")); | |
return dataSource; | |
} | |
@Bean | |
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) { | |
JpaTransactionManager transactionManager = new JpaTransactionManager(); | |
transactionManager.setEntityManagerFactory(emf); | |
return transactionManager; | |
} | |
@Bean | |
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { | |
return new PersistenceExceptionTranslationPostProcessor(); | |
} | |
private Properties additionalProperties() { | |
Properties properties = new Properties(); | |
properties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto")); | |
properties.setProperty("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect")); | |
properties.setProperty("hibernate.current_session_context_class", env.getProperty("spring.jpa.properties.hibernate.current_session_context_class")); | |
properties.setProperty("hibernate.jdbc.lob.non_contextual_creation", env.getProperty("spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation")); | |
properties.setProperty("hibernate.show_sql", env.getProperty("spring.jpa.show-sql")); | |
properties.setProperty("hibernate.format_sql", env.getProperty("spring.jpa.properties.hibernate.format_sql")); | |
return properties; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.thomasvitale.jpa.demo.model; | |
import javax.persistence.*; | |
@Entity | |
@Table(name = "persons") | |
public class Person { | |
@Id | |
@GeneratedValue(strategy = GenerationType.AUTO) | |
private Integer id; | |
@Column(name = "first_name", nullable = false) | |
private String firstName; | |
@Column(name = "last_name", nullable = false) | |
private String lastName; | |
@Column(name = "ssn", nullable = false, unique = true) | |
private String ssn; | |
public Person() { | |
} | |
public Person(String firstName, String lastName) { | |
this.firstName = firstName; | |
this.lastName = lastName; | |
} | |
public Person(String firstName, String lastName, String ssn) { | |
this(firstName, lastName); | |
this.ssn = ssn; | |
} | |
public Integer getId() { | |
return id; | |
} | |
public void setId(Integer id) { | |
this.id = id; | |
} | |
public String getFirstName() { | |
return firstName; | |
} | |
public void setFirstName(String firstName) { | |
this.firstName = firstName; | |
} | |
public String getLastName() { | |
return lastName; | |
} | |
public void setLastName(String lastName) { | |
this.lastName = lastName; | |
} | |
public String getSsn() { | |
return ssn; | |
} | |
public void setSsn(String ssn) { | |
this.ssn = ssn; | |
} | |
@Override | |
public String toString() { | |
return firstName + " " + lastName; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.thomasvitale.jpa.demo.repository; | |
import com.thomasvitale.jpa.demo.model.Person; | |
import org.springframework.data.jpa.repository.JpaRepository; | |
import org.springframework.stereotype.Repository; | |
import java.util.List; | |
@Repository | |
public interface PersonRepository extends JpaRepository<Person, Integer> { | |
List<Person> findByFirstName(String firstName); | |
List<Person> findByLastName(String lastName); | |
Person findBySsn(String ssn); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment