JAVA-66: New module spring-data-jpa-crud
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
## Spring Data JPA - CRUD
|
||||
|
||||
This module contains articles about CRUD operations in Spring Data JPA
|
||||
|
||||
### Relevant Articles:
|
||||
- [Spring Data JPA – Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby)
|
||||
- [Spring Data JPA Delete and Relationships](https://www.baeldung.com/spring-data-jpa-delete)
|
||||
- [INSERT Statement in JPA](https://www.baeldung.com/jpa-insert)
|
||||
- [Spring Data JPA Batch Inserts](https://www.baeldung.com/spring-data-jpa-batch-inserts)
|
||||
- [Batch Insert/Update with Hibernate/JPA](https://www.baeldung.com/jpa-hibernate-batch-insert-update)
|
||||
- [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush)
|
||||
- [Generate Database Schema with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-generate-db-schema)
|
||||
|
||||
### Eclipse Config
|
||||
After importing the project into Eclipse, you may see the following error:
|
||||
"No persistence xml file found in project"
|
||||
|
||||
This can be ignored:
|
||||
- Project -> Properties -> Java Persistance -> JPA -> Error/Warnings -> Select Ignore on "No persistence xml file found in project"
|
||||
Or:
|
||||
- Eclipse -> Preferences - Validation - disable the "Build" execution of the JPA Validator
|
||||
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-data-jpa-crud</artifactId>
|
||||
<name>spring-data-jpa-crud</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- Prod Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ttddyy</groupId>
|
||||
<artifactId>datasource-proxy</artifactId>
|
||||
<version>${datasource-proxy.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Test containers only dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${testcontainers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Test containers only dependencies -->
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<datasource-proxy.version>1.4.1</datasource-proxy.version>
|
||||
<guava.version>21.0</guava.version>
|
||||
<testcontainers.version>1.12.2</testcontainers.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableJpaRepositories
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.baeldung.batchinserts;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.sql.DataSource;
|
||||
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
@Component
|
||||
@Profile("batchinserts")
|
||||
public class DatasourceProxyBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
|
||||
if (bean instanceof DataSource) {
|
||||
ProxyFactory factory = new ProxyFactory(bean);
|
||||
factory.setProxyTargetClass(true);
|
||||
factory.addAdvice(new ProxyDataSourceInterceptor((DataSource) bean));
|
||||
return factory.getProxy();
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private static class ProxyDataSourceInterceptor implements MethodInterceptor {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public ProxyDataSourceInterceptor(final DataSource dataSource) {
|
||||
this.dataSource = ProxyDataSourceBuilder.create(dataSource).name("Batch-Insert-Logger").asJson().countQuery().logQueryToSysOut().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||
Method proxyMethod = ReflectionUtils.findMethod(dataSource.getClass(), invocation.getMethod().getName());
|
||||
if (proxyMethod != null) {
|
||||
return proxyMethod.invoke(dataSource, invocation.getArguments());
|
||||
}
|
||||
return invocation.proceed();
|
||||
}
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.baeldung.batchinserts.model;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
@Entity
|
||||
public class School {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy = "school")
|
||||
private List<Student> students;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Student> getStudents() {
|
||||
return students;
|
||||
}
|
||||
|
||||
public void setStudents(List<Student> students) {
|
||||
this.students = students;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.batchinserts.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class Student {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@ManyToOne
|
||||
private School school;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public School getSchool() {
|
||||
return school;
|
||||
}
|
||||
|
||||
public void setSchool(School school) {
|
||||
this.school = school;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.boot;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableJpaRepositories("com.baeldung")
|
||||
@EntityScan("com.baeldung")
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.boot.daos;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baeldung.boot.domain.Customer;
|
||||
|
||||
/**
|
||||
* JPA CrudRepository interface
|
||||
*
|
||||
* @author ysharma2512
|
||||
*
|
||||
*/
|
||||
@Repository
|
||||
@Transactional
|
||||
public interface CustomerRepository extends CrudRepository<Customer, Long>{
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.boot.daos.impl;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.baeldung.boot.domain.Person;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
@Repository
|
||||
public class PersonInsertRepository {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Transactional
|
||||
public void insertWithQuery(Person person) {
|
||||
entityManager.createNativeQuery("INSERT INTO person (id, first_name, last_name) VALUES (?,?,?)")
|
||||
.setParameter(1, person.getId())
|
||||
.setParameter(2, person.getFirstName())
|
||||
.setParameter(3, person.getLastName())
|
||||
.executeUpdate();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void insertWithEntityManager(Person person) {
|
||||
this.entityManager.persist(person);
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.baeldung.boot.domain;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* Customer Entity class
|
||||
* @author ysharma2512
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
public class Customer {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public Customer(String firstName, String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName);
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.baeldung.boot.domain;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(Long id, String firstName, String lastName) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long 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;
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.boot.web.controllers;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.boot.daos.CustomerRepository;
|
||||
import com.baeldung.boot.domain.Customer;
|
||||
|
||||
/**
|
||||
* A simple controller to test the JPA CrudRepository operations
|
||||
* controllers
|
||||
*
|
||||
* @author ysharma2512
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
public class CustomerController {
|
||||
|
||||
CustomerRepository customerRepository;
|
||||
|
||||
public CustomerController(CustomerRepository customerRepository2) {
|
||||
this.customerRepository = customerRepository2;
|
||||
}
|
||||
|
||||
@PostMapping("/customers")
|
||||
public ResponseEntity<List<Customer>> insertCustomers() throws URISyntaxException {
|
||||
Customer c1 = new Customer("James", "Gosling");
|
||||
Customer c2 = new Customer("Doug", "Lea");
|
||||
Customer c3 = new Customer("Martin", "Fowler");
|
||||
Customer c4 = new Customer("Brian", "Goetz");
|
||||
List<Customer> customers = Arrays.asList(c1, c2, c3, c4);
|
||||
customerRepository.saveAll(customers);
|
||||
return ResponseEntity.ok(customers);
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.datajpadelete.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class Book {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
private String title;
|
||||
|
||||
@ManyToOne
|
||||
private Category category;
|
||||
|
||||
public Book() {
|
||||
}
|
||||
|
||||
public Book(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Book(String title, Category category) {
|
||||
this.title = title;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Category getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(Category category) {
|
||||
this.category = category;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.baeldung.datajpadelete.entity;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Entity
|
||||
public class Category {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
private List<Book> books;
|
||||
|
||||
public Category() {
|
||||
}
|
||||
|
||||
public Category(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Category(String name, Book... books) {
|
||||
this.name = name;
|
||||
this.books = Stream.of(books).collect(Collectors.toList());
|
||||
this.books.forEach(x -> x.setCategory(this));
|
||||
}
|
||||
|
||||
public Category(String name, List<Book> books) {
|
||||
this.name = name;
|
||||
this.books = books;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Book> getBooks() {
|
||||
return books;
|
||||
}
|
||||
|
||||
public void setBooks(List<Book> books) {
|
||||
this.books = books;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.datajpadelete.repository;
|
||||
|
||||
import com.baeldung.datajpadelete.entity.Book;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface BookRepository extends CrudRepository<Book, Long> {
|
||||
|
||||
long deleteByTitle(String title);
|
||||
|
||||
@Modifying
|
||||
@Query("delete from Book b where b.title=:title")
|
||||
void deleteBooks(@Param("title") String title);
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.datajpadelete.repository;
|
||||
|
||||
import com.baeldung.datajpadelete.entity.Category;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CategoryRepository extends CrudRepository<Category, Long> {
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.entity;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Employee {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
public Employee() {
|
||||
}
|
||||
|
||||
public Employee(Long id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.entity;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
@XmlRootElement
|
||||
@Entity
|
||||
public class Fruit {
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
private String name;
|
||||
private String color;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.baeldung.entity.Employee;
|
||||
|
||||
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.baeldung.entity.Fruit;
|
||||
|
||||
@Repository
|
||||
public interface FruitRepository extends JpaRepository<Fruit, Long> {
|
||||
|
||||
Long deleteByName(String name);
|
||||
|
||||
List<Fruit> deleteByColor(String color);
|
||||
|
||||
Long removeByName(String name);
|
||||
|
||||
List<Fruit> removeByColor(String color);
|
||||
|
||||
@Modifying
|
||||
@Query("delete from Fruit f where f.name=:name or f.color=:color")
|
||||
int deleteFruits(@Param("name") String name, @Param("color") String color);
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.schemageneration;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class AccountApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AccountApplication.class, args);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.baeldung.schemageneration;
|
||||
|
||||
import com.baeldung.schemageneration.model.Account;
|
||||
import com.baeldung.schemageneration.model.AccountSetting;
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||
import org.hibernate.tool.schema.TargetType;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class HibernateUtil {
|
||||
|
||||
/**
|
||||
* Generates database create commands for the specified entities using Hibernate native API, SchemaExport.
|
||||
* Creation commands are exported into the create.sql file.
|
||||
*/
|
||||
public static void generateSchema() {
|
||||
Map<String, String> settings = new HashMap<>();
|
||||
settings.put(Environment.URL, "jdbc:h2:mem:schema");
|
||||
|
||||
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(settings).build();
|
||||
|
||||
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||
metadataSources.addAnnotatedClass(Account.class);
|
||||
metadataSources.addAnnotatedClass(AccountSetting.class);
|
||||
Metadata metadata = metadataSources.buildMetadata();
|
||||
|
||||
SchemaExport schemaExport = new SchemaExport();
|
||||
schemaExport.setFormat(true);
|
||||
schemaExport.setOutputFile("create.sql");
|
||||
schemaExport.createOnly(EnumSet.of(TargetType.SCRIPT), metadata);
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package com.baeldung.schemageneration.model;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "accounts")
|
||||
public class Account {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, length = 100)
|
||||
private String name;
|
||||
|
||||
@Column(name = "email_address")
|
||||
private String emailAddress;
|
||||
|
||||
@OneToMany(mappedBy = "account", cascade = CascadeType.ALL)
|
||||
private List<AccountSetting> accountSettings = new ArrayList<>();
|
||||
|
||||
public Account() {
|
||||
}
|
||||
|
||||
public Account(String name, String emailAddress) {
|
||||
this.name = name;
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getEmailAddress() {
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public void setEmailAddress(String emailAddress) {
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
public List<AccountSetting> getAccountSettings() {
|
||||
return accountSettings;
|
||||
}
|
||||
|
||||
public void setAccountSettings(List<AccountSetting> accountSettings) {
|
||||
this.accountSettings = accountSettings;
|
||||
}
|
||||
|
||||
public void addAccountSetting(AccountSetting setting) {
|
||||
this.accountSettings.add(setting);
|
||||
setting.setAccount(this);
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.baeldung.schemageneration.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "account_settings")
|
||||
public class AccountSetting {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@Column(name = "name", nullable = false)
|
||||
private String settingName;
|
||||
|
||||
@Column(name = "value", nullable = false)
|
||||
private String settingValue;
|
||||
|
||||
@ManyToOne()
|
||||
@JoinColumn(name ="account_id", nullable = false)
|
||||
private Account account;
|
||||
|
||||
public AccountSetting() {
|
||||
}
|
||||
|
||||
public AccountSetting(String settingName, String settingValue) {
|
||||
this.settingName = settingName;
|
||||
this.settingValue = settingValue;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSettingName() {
|
||||
return settingName;
|
||||
}
|
||||
|
||||
public void setSettingName(String settingName) {
|
||||
this.settingName = settingName;
|
||||
}
|
||||
|
||||
public String getSettingValue() {
|
||||
return settingValue;
|
||||
}
|
||||
|
||||
public void setSettingValue(String settingValue) {
|
||||
this.settingValue = settingValue;
|
||||
}
|
||||
|
||||
public Account getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public void setAccount(Account account) {
|
||||
this.account = account;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.baeldung.schemageneration.repository;
|
||||
|
||||
import com.baeldung.schemageneration.model.Account;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface AccountRepository extends CrudRepository<Account, Long> {
|
||||
Account findByName(String name);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.baeldung.schemageneration.repository;
|
||||
|
||||
import com.baeldung.schemageneration.model.AccountSetting;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface AccountSettingRepository extends CrudRepository<AccountSetting, Long> {
|
||||
AccountSetting findByAccountId(Long accountId);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
spring.main.allow-bean-definition-overriding=true
|
||||
|
||||
spring.jpa.properties.hibernate.jdbc.batch_size=4
|
||||
spring.jpa.properties.hibernate.order_inserts=true
|
||||
spring.jpa.properties.hibernate.order_updates=true
|
||||
spring.jpa.properties.hibernate.generate_statistics=true
|
||||
|
||||
# JPA-Schema-Generation
|
||||
# Use below configuration to generate database schema create commands based on the entity models
|
||||
# and export them into the create.sql file
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata
|
||||
#spring.jpa.properties.hibernate.format_sql=true
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.boot.Application;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Application.class)
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.boot.Application;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
@ContextConfiguration(classes = Application.class)
|
||||
public class SpringJpaContextIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user