- 0001 - Master Hibernate and JPA with Spring Boot - Preview
- 0002 - Master Hibernate and JPA with Spring Boot - Course Overview
- 0003 - Master Hibernate and JPA with Spring Boot - Git Repository
- 0004 - Master Hibernate and JPA with Spring Boot - Installing Basic Tools
- 0005 - Quick introduction to JPA
- 0000 - Section Introduction - Introduction to Spring Boot in 10 Steps
- Step 1 : Introduction to Spring Boot - Goals and Important Features
- Step 2 : Developing Spring Applications before Spring Boot
- Step 3 : Using Spring Initializr to create a Spring Boot Application
- Step 4 : Creating a Simple REST Controller
- Step 5 : What is Spring Boot Auto Configuration?
- Step 6 : Spring Boot vs Spring vs Spring MVC
- Step 7 : Spring Boot Starter Projects - Starter Web and Starter JPA
- Step 8 : Overview of different Spring Boot Starter Projects
- Step 9 : Spring Boot Actuator
- Step 10 : Spring Boot Developer Tools
- 0000 - Section Introduction - Introduction to Journey from JDBC To JPA
- Step 01 - Setting up a project with JDBC, JPA, H2 and Web Dependencies
- Step 02 - Launching up H2 Console
- Step 03 - Creating a Database Table in H2
- Step 04 - Populate data into Person Table
- Step 05 - Implement findAll persons Spring JDBC Query Method
- Step 06 - Execute the findAll method using CommandLineRunner
- Step 07 - A Quick Review - JDBC vs Spring JDBC
- Step 08 - Whats in the background? Understanding Spring Boot Autoconfiguration
- Step 09 - Implementing findById Spring JDBC Query Method
- Step 10 - Implementing deleteById Spring JDBC Update Method
- Step 11 - Implementing insert and update Spring JDBC Update Methods
- Step 12 - Creating a custom Spring JDBC RowMapper
- Step 13 - Quick introduction to JPA
- Step 14 - Defining Person Entity
- Step 15 - Implementing findById JPA Repository Method
- Step 16 - Implementing insert and update JPA Repository Methods
- Step 17 - Implementing deleteById JPA Repository Method
- Step 18 - Implementing findAll using JPQL Named Query
- 0000 - Section Introduction - Introduction to JUnit in 5 Steps
- Step 1 : What is JUnit and Unit Testing?
- Step 2 : First JUnit Project and Green Bar
- Step 3 : First Code and First Unit Test
- Step 4 : Other assert methods
- Step 5 : Important annotations
- 0000 - Section Introduction - Introduction to JPA and Hibernate in Depth
- Step 01 - Create a JPA Project with H2 and Spring Boot
- Step 02 - Create JPA Entity Course
- Step 03 - Create findById using JPA Entity Manager
- Step 04 - Configuring application.properties to enable H2 console and logging
- Step 05 - Writing Unit Test for findById method
- Step 06 - Writing a deleteByID method to delete an Entity
- Step 07 - Writing Unit Test for deleteById method
- Step 08 - Writing a save method to update and insert an Entity
- Step 09 - Writing Unit Test for save method
- Step 10 - Quick Review and Debugging Tips
- Step 11 - Playing with Entity Manager
- Step 12 - Entity Manager Methods - clear and detach
- Step 13 - Entity Manager Methods - refresh
- Step 14 - A Quick Review of Entity Manager
- Step 15 - JPQL - Basics
- Step 16 - JPA and Hibernate Annotations - @Table
- Step 17 - JPA and Hibernate Annotations - @Column
- Step 18 - JPA and Hibernate Annotations - @UpdateTimestamp and @CreationTimestamp
- Step 19 - JPA and Hibernate Annotations - @NamedQuery and @NamedQueries
- Step 20 - Native Queries - Basics
- Step 21 - Entities and Relationships - An overview
- Step 22 - Defining Entities - Student, Passport and Review
- Step 23 - Introduction to One to One Relationship
- Step 24 - OneToOne Mapping - Insert Student with Passport
- Step 25 - OneToOne Mapping - Retrieving Student with Passport and Eager Fetch
- Step 26 - OneToOne Mapping - Lazy Fetch
- Step 27 - Transaction, Entity Manager and Persistence Context
- Step 28 - OneToOne Mapping - Bidirectional Relationship - Part 1
- Step 29 - OneToOne Mapping - Bidirectional Relationship - Part 2
- Step 30 - ManyToOne Mapping - Designing the database
- Step 30 - 02 - ManyToOne Mapping - Implementing the Mapping *****
- Step 31 - ManyToOne Mapping - Retrieving and inserting Reviews for Course
- Step 32 - ManyToOne Mapping - Generalizing Insert Reviews
- Step 33 - ManyToOne Mapping - Wrapping up
- Step 34 - ManyToMany Mapping - Table Design
- Step 35 - ManyToMany Mapping - Adding Annotations on Entities
- Step 36 - ManyToMany Mapping - Fixing two join tables problem
- Step 37 - ManyToMany Mapping - Customizing the Join Table
- Step 38 - ManyToMany Mapping - Insert Data and Write Join Query
- Step 39 - ManyToMany Mapping - Retrieve Data using JPA Relationships
- Step 40 - ManyToMany Mapping - Insert Student and Course
- Step 41 - Relationships between JPA Entities - A summary
- Step 42 - Introduction to Inheritance Hierarchies and Mappings
- Step 43 - JPA Inheritance Hierarchies and Mappings - Setting up entities
- Step 44 - JPA Inheritance Hierarchies and Mappings - Setting up a Repository
- Step 45 - JPA Inheritance Hierarchies and Mappings - Single Table
- Step 46 - JPA Inheritance Hierarchies and Mappings - Table Per Class
- Step 47 - JPA Inheritance Hierarchies and Mappings - Joined
- Step 48 - JPA Inheritance Hierarchies and Mappings - Mapped Super Class
- Step 49 - JPA Inheritance Hierarchies and Mappings - How to Choose?
- Step 50 - JPQL - Courses without Students
- Step 51 - JPQL - Courses with atleast 2 Students and order by
- Step 52 - JPQL - Courses like 100 Steps
- Step 53 - JPQL - Using Joins
- Step 54 - Criteria Query - Retrieving all courses
- Step 55 - Criteria Query - Courses like 100 Steps
- Step 56 - Criteria Query - Courses without Students
- Step 57 - Criteria Query - Using Joins
- Step 58 - Introduction to Transaction Management
- Step 59 - Transaction Management - ACID Properties
- Step 60 - Understanding Dirty, Phanthom and Non Repeatable Reads
- Step 61 - Understand 4 Isolation Levels
- Step 62 - Choosing between Isolation Levels
- Step 63 - Implementing Transaction Management - 3 Things to Decide
- Step 64 - Introduction to Spring Data JPA
- Step 65 - Testing the Spring Data JPA Repository with findById.
- Step 66 - Spring Data JPA Repository - CRUD Methods
- Step 67 - Sorting using Spring Data JPA Repository
- Step 68 - Pagination using Spring Data JPA Repository
- Step 69 - Custom Queries using Spring Data JPA Repository
- Step 70 - Spring Data REST
- Step 71 - Introduction to Caching
- Step 72 - Hibernate and JPA Caching - First Level Cache
- Step 73 - Hibernate and JPA Caching - Basics of Second Level Cache with EhCache
- Step 74 - Hibernate and JPA Caching - Second Level Cache Part 2
- Step 75 - Hibernate Tips - Hibernate Soft Deletes - @SQLDelete and @Where
- Step 76 - Hibernate Soft Deletes - Part 2
- Step 77 - JPA Entity Life Cycle Methods
- Step 78 - Using Embedded and Embeddable with JPA
- Step 79 - Using Enums with JPA
- Step 80 - JPA Tip - Be cautious with toString method implementations
- Step 81 - JPA Tip - When do you use JPA?
- Step 82 - Performance Tuning - Measure before Tuning
- Step 83 - Performance Tuning - Indexes
- Step 84 - Performance Tuning - Use Appropriate Caching
- Step 85 - Performance Tuning - Eager vs Lazy Fetch
- Step 86 - Performance Tuning - Avoid N+1 Problems
TO Decide
- FAQ 1 - When does Hibernate send updates to the database?
- FAQ 2 - When do we need @Transactional in an Unit Test?
- FAQ 3 - Do read only methods need a transaction?
- FAQ 4 - Why do we use @DirtiesContext in an Unit Test?
- FAQ 5 - How to connect to a different database with Spring Boot?
- FAQ 6 - Approach to design great applications with JPA?
- FAQ 7 - Good Practices for developing JPA Applications
- 9999 - Master Hibernate & JPA with Spring Boot - Congratulations on Completing the Course
- 0000 - Section Introduction - Introduction to Spring Framework in 10 Steps
- Step 1 - Setting up a Spring Project using htttp://start.spring.io
- Step 2 - Understanding Tight Coupling using the Binary Search Algorithm Example
- Step 3 - Making the Binary Search Algorithm Example Loosely Coupled
- Step 4 - Using Spring to Manage Dependencies - @Component, @Autowired
- Step 5 - What is happening in the background?
- Step 6 - Dynamic auto wiring and Troubleshooting - @Primary
- Step 7 - Constructor and Setter Injection
- Step 8 - Spring Modules
- Step 9 - Spring Projects
- Step 10 - Why is Spring Popular?
- Do Read Only methods need a transaction?
- Entities - User, Comment
@Transactional
List<Comment> someReadOnlyMethod() {
User user = em.find(User.class, 1L);
List<Comment> comments = user.getComments();//
return comments;
}
- Why do we need @Transactional in Unit Tests some times?
- Unit Test -> Repository -> EntityManager
- Unit Test -> EntityManager
- When does Hibernate fire queries down to database?
@Transactional
void someMethodWithChange() {
//Create Objects
em.persist(user1);
em.persist(user2);
em.flush();
//Change user1
//Change user2
}
//all changes are saved down to the database!
<hibernate-mapping>
<class name="Person" table="person">
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="role" column="role " type="integer"/>
</class>
</hibernate-mapping>
- detach method
- clear method
- flush method
- @Table : Indicates table name.
- @Column : Defining Constraints on Columns.
- @NamedQueries Indicates list of named queries.
- @NamedQuery Indicates a Query using static name.
- @CreationTimestamp
- @UpdateTimestamp
- @Transient : Column will not be persisted.
- @PostLoad
- Discuss the basics here
@NamedQueries({
@NamedQuery(name="name1",
query="Query1"),
@NamedQuery(name="name2",
query="Query2"),
})
- We can discuss the stuff needing Join after discussing relationships
- Database specific feature
- Three types of relationships
-
best performance - single table strategy
-
best data integrity - joined
-
JPQL queries with Joins
- basic_empty_courses
- basic_courses_with_min_three_students
// 1. Use Criteria Builder to create a Criteria Query returning the
// expected result object
// 2. Define roots for tables which are involved in the query
// 3. Define Predicates etc using Criteria Builder
// 4. Add Predicates etc to the Criteria Query
// 5. Build the TypedQuery using the entity manager and criteria query
- Spring vs JPA @Transactional
- Isolation Levels
- Transactions have importance even within read-only context - like specifying a database isolation-level. We strongly recommend that all database operations occur within the scope of some transaction.
- basic_courses_order_by
- join
- left_outer_join
- cross_join
- join
- left_outer_join
- Spring Data REST
- First Level Cache Demo
- Second Level Cache Demo
- Implementing Soft Deletes - @Where and @SQLDelete
- Embedded Entities
- Using Enumerations With JPA
- Be cautious about toString
- Be cautious about Eager fetching on both sides of a relationship
- When do you use JPA?
- SQL Database + Static Domain Model + Mostly CRUD + Mostly Simple Queries/Mappings and Updates with few Stored Procedures
- Zero Performance Tuning without Statistics. Check Stats in atleast one environment.
- Do not use JPA/Hibernate for Database intensive Batch Operations - Use Stored Procedures
- Add the right indexes on the database - Execution Plan
- Use Appropriate Caching
- Be careful about the size of First Level Cache
- Eager vs Lazy Fetch - Use Lazy fetching mostly
- Remember that all mapping *ToOne (@ManyToOne and @OneToOne) are EAGER by default.
- Avoid N+1
- Entity Graph & Named Entity Graphs & Dynamic Entity Graphs
- Join Fetch Clause
- Use Pagination & Batch Updates
query.setFirstResult(0);
query.setMaxResults(10);
- @Immutable - zero dirty checks!
- Read only transactions
<?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>
<groupId>com.in28minutes.jpa</groupId>
<artifactId>jpa-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jpa-demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArguments>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>process-sources</phase>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/annotations</source>
</sources>
</configuration>
<goals>
<goal>add-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>maven-annotation</id>
<url>http://maven-annotation-plugin.googlecode.com/svn/trunk/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
</project>
package com.in28minutes.jpa.jpademo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.in28minutes.jpa.jpademo.relationships.entity.Course;
import com.in28minutes.jpa.jpademo.relationships.repository.CourseRepository;
@RestController
public class CourseController {
@Autowired
CourseRepository repository;
@GetMapping("/courses/{id}")
public Course retrieveCourse(@PathVariable long id){
return repository.retrieveCourse(id);
}
}
package com.in28minutes.jpa.jpademo.embedded.entity;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
//@Embeddable
public class Name {
@Id
@GeneratedValue
protected Long id;
protected String firstName;
protected String middleName;
protected String lastName;
}
package com.in28minutes.jpa.jpademo.embedded.entity;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class Person {
@Id
@GeneratedValue
protected Long id;
@OneToOne
//@Embedded
protected Name name;
}
package com.in28minutes.jpa.jpademo.inheritence.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.MappedSuperclass;
//@MappedSuperclass
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
// @DiscriminatorColumn(name = "disc_type")
public abstract class Employee {
public Employee() {
}
public Employee(String name) {
this.name = name;
}
@GeneratedValue
@Id
protected Integer id;
private String name;
}
package com.in28minutes.jpa.jpademo.inheritence.entity;
import java.math.BigDecimal;
import javax.persistence.Entity;
@Entity
public class FullTimeEmployee extends Employee {
public FullTimeEmployee(){}
public FullTimeEmployee(String name, BigDecimal salary) {
super(name);
this.salary = salary;
}
protected BigDecimal salary;
}
package com.in28minutes.jpa.jpademo.inheritence.entity;
import java.math.BigDecimal;
import javax.persistence.Entity;
@Entity
public class PartTimeEmployee extends Employee {
public PartTimeEmployee(){}
public PartTimeEmployee(String name, BigDecimal hourlyWage) {
super(name);
this.hourlyWage = hourlyWage;
}
protected BigDecimal hourlyWage;
}
package com.in28minutes.jpa.jpademo.inheritence.repository;
import java.util.List;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.in28minutes.jpa.jpademo.inheritence.entity.Employee;
@Transactional
@Repository
public class EmployeeRepository {
@Autowired
EntityManager entityManager;
public void insertEmployee(Employee employee) {
entityManager.persist(employee);
}
public List<Employee> allEmployees() {
return entityManager.createQuery("Select e from Employee e", Employee.class).getResultList();
}
}
package com.in28minutes.jpa.jpademo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.in28minutes.jpa.jpademo.inheritence.repository.EmployeeRepository;
import com.in28minutes.jpa.jpademo.relationships.repository.StudentRepository;
@SpringBootApplication
public class JpaDemoApplication implements CommandLineRunner {
@Autowired
StudentRepository studentRepository;
@Autowired
EmployeeRepository employeeRepository;
public static void main(String[] args) {
SpringApplication.run(JpaDemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
}
}
package com.in28minutes.jpa.jpademo.relationships.entity;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
@Entity
@Table(name = "Course")
@NamedQuery(query = "select c from Course c", name = "QUERY_ALL_COURSES")
@NamedEntityGraph(name = "graph.CourseAndStudents",
attributeNodes = @NamedAttributeNode(value = "students"/*, subgraph = "students"),*/)
/*subgraphs = @NamedSubgraph(name = "students", attributeNodes = @NamedAttributeNode("passport"))*/)
@Cacheable
public class Course {
public Course() {
}
public Course(String name) {
super();
this.name = name;
}
@Id
@GeneratedValue
protected Long id;
protected String name;
// @OneToMany
@OneToMany(mappedBy = "course")
protected List<Review> reviews = new ArrayList<>();
@ManyToMany
// @JoinTable(name = "COURSE_STUDENT",
// joinColumns = @JoinColumn(name = "COURSE_ID"),
// inverseJoinColumns = @JoinColumn(name = "STUDENT_ID"))
protected List<Student> students = new ArrayList<>();
@CreationTimestamp
private LocalDateTime createDateTime;
private LocalDate activeFrom;
@UpdateTimestamp
private LocalDateTime updateDateTime;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Review> getReviews() {
return reviews;
}
public void addReview(Review review) {
this.reviews.add(review);
}
public List<Student> getStudents() {
return students;
}
public void addStudent(Student student) {
this.students.add(student);
}
public LocalDate getActiveFrom() {
return activeFrom;
}
public void setActiveFrom(LocalDate activeFrom) {
this.activeFrom = activeFrom;
}
@Override
public String toString() {
return String.format("Course[%s]", name);
}
}
package com.in28minutes.jpa.jpademo.relationships.entity;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.validation.constraints.NotNull;
import org.hibernate.annotations.Where;
@Entity
@Where(clause = "1=1")
public class Passport {
protected Passport() {
}
public Passport(String number) {
super();
this.number = number;
}
@Id
@GeneratedValue
protected Long id;
@NotNull
protected String number;
// Inverse Relationship
// bi-directional OneToOne relationship
// Column will not be created in the table
// Try removing mappedBy = "passport" => You will see a student_id column
// will be created in passport
// @OneToOne
@OneToOne(fetch = FetchType.LAZY, mappedBy = "passport")
protected Student student;
public Long getId() {
return id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
package com.in28minutes.jpa.jpademo.relationships.entity;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
public class Review {
private Review() {}
public Review(ReviewRating rating, String description) {
super();
this.rating = rating;
this.description = description;
}
@Id
@GeneratedValue
protected Long id;
@Enumerated
protected ReviewRating rating;
protected String description;
@ManyToOne
// @JoinColumn(name="COURSE_ID")
protected Course course;
public Long getId() {
return id;
}
public ReviewRating getRating() {
return rating;
}
public void setRating(ReviewRating rating) {
this.rating = rating;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
}
package com.in28minutes.jpa.jpademo.relationships.entity;
public enum ReviewRating {
ONE,TWO,THREE,FOUR,FIVE
}
package com.in28minutes.jpa.jpademo.relationships.entity;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.MapKeyColumn;
import javax.persistence.MapKeyEnumerated;
import javax.persistence.OneToOne;
import org.hibernate.annotations.SQLDelete;
@Entity
@SQLDelete(sql = "UPDATE student SET state = 'DELETED' WHERE id = ?")
public class Student {
private Student() {
}
public Student(String name, StudentType studentType) {
super();
this.name = name;
this.studentType = studentType;
}
@Id
@GeneratedValue
protected Long id;
protected String name;
@OneToOne(fetch = FetchType.LAZY)
protected Passport passport;
// @ManyToMany
@ManyToMany(mappedBy = "students")
protected List<Course> courses = new ArrayList<>();
// @Enumerated
@Enumerated(EnumType.STRING)
private StudentType studentType;
@ElementCollection
@CollectionTable(name = "STUDENT_PHONE")
@MapKeyEnumerated(EnumType.STRING)
@MapKeyColumn(name = "PHONE_TYPE")
@Column(name = "PHONE_NUM")
private Map<PhoneType, String> phoneNumbers;
enum PhoneType {
Home, Mobile, Work
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Passport getPassport() {
return passport;
}
public void setPassport(Passport passport) {
this.passport = passport;
}
public List<Course> getCourses() {
return courses;
}
public void addCourse(Course course) {
courses.add(course);
}
public StudentType getStudentType() {
return studentType;
}
public void setStudentType(StudentType studentType) {
this.studentType = studentType;
}
public Map<PhoneType, String> getPhoneNumbers() {
return phoneNumbers;
}
public void addPhoneNumber(PhoneType phoneType, String number) {
phoneNumbers.put(phoneType, number);
}
@Override
public String toString() {
return String.format("Student[%s]", name);
}
}
package com.in28minutes.jpa.jpademo.relationships.entity;
public enum StudentType {
FullTime, PartTime
}
package com.in28minutes.jpa.jpademo.relationships.repository;
import java.util.List;
import javax.persistence.EntityGraph;
import javax.persistence.EntityManager;
import javax.persistence.Subgraph;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.in28minutes.jpa.jpademo.relationships.entity.Course;
import com.in28minutes.jpa.jpademo.relationships.entity.Course_;
import com.in28minutes.jpa.jpademo.relationships.entity.Review;
import com.in28minutes.jpa.jpademo.relationships.entity.Student;
@Repository
@Transactional
public class CourseRepository {
@Autowired
EntityManager entityManager;
public void createCourse(Course course) {
entityManager.persist(course);
}
public Course retrieveCourse(Long id) {
return entityManager.find(Course.class, id);
}
public void printAllCourseAndStudents() {
EntityGraph graph = entityManager.getEntityGraph("graph.CourseAndStudents");
List<Course> courses = entityManager.createQuery("Select c from Course c", Course.class)
.setHint("javax.persistence.loadgraph", graph).getResultList();
for (Course course : courses) {
System.out.println(course + " " + course.getStudents());
}
}
public void printAllCourseAndStudentsDynamicSubgraph() {
EntityGraph<Course> graph = entityManager.createEntityGraph(Course.class);
Subgraph<List<Student>> bookSubGraph = graph.addSubgraph(Course_.students);
List<Course> courses = entityManager.createQuery("Select c from Course c", Course.class)
.setHint("javax.persistence.loadgraph", graph).getResultList();
for (Course course : courses) {
System.out.println(course + " " + course.getStudents());
}
}
public void printAllCourseAndStudentsJoinFetch() {
List<Course> courses = entityManager.createQuery("Select c from Course c JOIN FETCH c.students s", Course.class)
.getResultList();
for (Course course : courses) {
System.out.println(course + " " + course.getStudents());
}
}
public void updateCourse(Course course) {
entityManager.merge(course);
}
public void createCourseWithStudents(Course course, Student... students) {
for (Student student : students) {
course.addStudent(student);
student.addCourse(course);
if (student.getId() == null) {
entityManager.persist(student);
}
}
createCourse(course);
}
public void createReviewsForCourse(Course course, Review... reviews) {
for (Review review : reviews) {
course.addReview(review);
review.setCourse(course);
if (review.getId() == null) {
entityManager.persist(review);
}
}
}
}
package com.in28minutes.jpa.jpademo.relationships.repository;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.in28minutes.jpa.jpademo.relationships.entity.Passport;
@Repository
@Transactional
public class EntityManagerRepository {
@Autowired
EntityManager entityManager;
public void doSomething() {
Passport passport = new Passport("E123456");
entityManager.persist(passport);
entityManager.flush();
passport.setNumber("E123457");
// entityManager.clear();
// entityManager.detach(passport);
// entityManager.refresh(passport);
// entityManager.remove(passport);
// entityManager.merge(passport);
// Queries
// Entity Graphs
}
}
package com.in28minutes.jpa.jpademo.relationships.repository;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.in28minutes.jpa.jpademo.relationships.entity.Course;
import com.in28minutes.jpa.jpademo.relationships.entity.Passport;
import com.in28minutes.jpa.jpademo.relationships.entity.Review;
import com.in28minutes.jpa.jpademo.relationships.entity.Student;
@Repository
@Transactional
public class StudentRepository {
@Autowired
EntityManager entityManager;
public void createStudentWithPassport(Student student, Passport passport) {
student.setPassport(passport);
//passport.setStudent(student);
entityManager.persist(passport);
entityManager.persist(student);
}
}
/src/main/java/com/in28minutes/jpa/jpademo/relationships/repository/TransactionManagementRepository.java
package com.in28minutes.jpa.jpademo.relationships.repository;
import javax.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.in28minutes.jpa.jpademo.relationships.entity.Passport;
@Repository
@Transactional
public class TransactionManagementRepository {
@Autowired
EntityManager entityManager;
public void doSomething() {
Passport passport1 = new Passport("E123456");
entityManager.persist(passport1);
Passport passport2 = new Passport(null);
entityManager.persist(passport2);
}
}
spring.h2.console.enabled=true
spring.jpa.properties.hibernate.generate_statistics=true
logging.level.org.hibernate.stat=debug
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
#logging.level.org.hibernate.type=TRACE
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
logging.level.net.sf.ehcache=debug
insert into course(id, name)
values(10101,'Caching in 100 Steps');
package com.in28minutes.jpa.jpademo;
import static org.junit.Assert.assertEquals;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
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 com.in28minutes.jpa.jpademo.relationships.entity.Course;
import com.in28minutes.jpa.jpademo.relationships.entity.Course_;
import com.in28minutes.jpa.jpademo.relationships.entity.Student;
@RunWith(SpringRunner.class)
@SpringBootTest // (webEnvironment = WebEnvironment.RANDOM_PORT)
public class CriteriaQueryDemoApplicationTest {
// @LocalServerPort
// String port;
@Autowired
EntityManager entityManager;
@Test
public void basic() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Course> cq = cb.createQuery(Course.class);
Root<Course> root = cq.from(Course.class);
TypedQuery<Course> query = entityManager.createQuery(cq.select(root));
List<Course> courses = query.getResultList();
System.out.println(courses);
}
@Test
public void basic2() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Course> cq = cb.createQuery(Course.class);
Root<Course> course = cq.from(Course.class);
Predicate condition = cb.like(course.get(Course_.name), "%100 Steps");
cq.where(condition);
TypedQuery<Course> query = entityManager.createQuery(cq.select(course));
List<Course> courses = query.getResultList();
System.out.println(courses);
assertEquals(2, courses.size());
System.out.println(courses);
}
@Test
public void basic_empty_courses() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Course> cq = cb.createQuery(Course.class);
Root<Course> course = cq.from(Course.class);
Predicate condition = cb.isEmpty(course.get(Course_.students));
cq.where(condition);
TypedQuery<Course> query = entityManager.createQuery(cq.select(course));
List<Course> courses = query.getResultList();
System.out.println(courses);
assertEquals(1, courses.size());
System.out.println(courses);
}
@Test
public void basic_courses_order_by() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Course> cq = cb.createQuery(Course.class);
Root<Course> course = cq.from(Course.class);
cq.orderBy(cb.desc(course.get(Course_.name)));
TypedQuery<Course> query = entityManager.createQuery(cq.select(course));
List<Course> courses = query.getResultList();
System.out.println(courses);
}
@Test
public void join() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Course> cq = cb.createQuery(Course.class);
Root<Course> course = cq.from(Course.class);
Join<Course, Student> student = course.join(Course_.students);
TypedQuery<Course> query = entityManager.createQuery(cq.select(course));
List<Course> courses = query.getResultList();
System.out.println(courses);
assertEquals(5, courses.size());
}
@Test
public void left_outer_join() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Course> cq = cb.createQuery(Course.class);
Root<Course> course = cq.from(Course.class);
Join<Course, Student> student = course.join(Course_.students, JoinType.LEFT);
TypedQuery<Course> query = entityManager.createQuery(cq.select(course));
List<Course> courses = query.getResultList();
System.out.println(courses);
assertEquals(6, courses.size());
}
}
package com.in28minutes.jpa.jpademo;
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 com.in28minutes.jpa.jpademo.relationships.repository.EntityManagerRepository;
@RunWith(SpringRunner.class)
@SpringBootTest // (webEnvironment = WebEnvironment.RANDOM_PORT)
public class EntityManagerDemoApplicationTests {
@Autowired
EntityManagerRepository entityManagerRepository;
@Test
public void someTest() {
entityManagerRepository.doSomething();
}
}
package com.in28minutes.jpa.jpademo;
import java.math.BigDecimal;
import javax.persistence.EntityManager;
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 com.in28minutes.jpa.jpademo.inheritence.entity.FullTimeEmployee;
import com.in28minutes.jpa.jpademo.inheritence.entity.PartTimeEmployee;
import com.in28minutes.jpa.jpademo.inheritence.repository.EmployeeRepository;
@RunWith(SpringRunner.class)
@SpringBootTest // (webEnvironment = WebEnvironment.RANDOM_PORT)
public class InheritanceDemoApplicationTest {
// @LocalServerPort
// String port;
@Autowired
EntityManager entityManager;
@Autowired
EmployeeRepository employeeRepository;
@Test
public void basic() {
employeeRepository.insertEmployee(new PartTimeEmployee("PartTimeEE", new BigDecimal(100)));
employeeRepository.insertEmployee(new FullTimeEmployee("FullTimeEE", new BigDecimal(10)));
System.out.println(employeeRepository.allEmployees());
}
}
package com.in28minutes.jpa.jpademo;
import java.time.LocalDate;
import java.time.Month;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import org.junit.After;
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 com.in28minutes.jpa.jpademo.relationships.entity.Course;
import com.in28minutes.jpa.jpademo.relationships.entity.Passport;
import com.in28minutes.jpa.jpademo.relationships.entity.Review;
import com.in28minutes.jpa.jpademo.relationships.entity.ReviewRating;
import com.in28minutes.jpa.jpademo.relationships.entity.Student;
import com.in28minutes.jpa.jpademo.relationships.entity.StudentType;
import com.in28minutes.jpa.jpademo.relationships.repository.CourseRepository;
import com.in28minutes.jpa.jpademo.relationships.repository.StudentRepository;
@RunWith(SpringRunner.class)
@SpringBootTest // (webEnvironment = WebEnvironment.RANDOM_PORT)
public class JpaDemoApplicationTests {
// @LocalServerPort
// String port;
@Autowired
EntityManager entityManager;
@Autowired
CourseRepository courseRepository;
@Autowired
StudentRepository studentRepository;
@Test
public void createCourseWithStudents() {
Student student = new Student("Ranga", StudentType.FullTime);
courseRepository.createCourseWithStudents(new Course("Spring in 100 Steps"), student);
courseRepository.createCourseWithStudents(new Course("Spring Boot in 100 Steps"), student);
}
@Test
public void createReviewsForCourse() {
Course course = new Course("JPA in 100 Steps");
courseRepository.createCourse(course);
courseRepository.createReviewsForCourse(course, new Review(ReviewRating.FIVE, "Awesome Course"),
new Review(ReviewRating.FIVE, "Wow!"));
}
@Test
public void createCourse() {
courseRepository.createCourse(new Course("JPA in 100 Steps"));
}
@Test
@Transactional
public void createStudentWithPassport() {
Student student = new Student("Ranga", StudentType.FullTime);
Passport passport = new Passport("A12345678");
studentRepository.createStudentWithPassport(student, passport);
}
@Test
public void updateCourse() {
Course course = courseRepository.retrieveCourse(10001L);
course.setName("JPA in 100 Steps - updated");
course.setActiveFrom(LocalDate.of(2018, Month.APRIL, 10));
courseRepository.updateCourse(course);
}
@After
public void printAllData() {
System.out.println("Dummy");
}
}
package com.in28minutes.jpa.jpademo;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
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 com.in28minutes.jpa.jpademo.relationships.entity.Course;
import com.in28minutes.jpa.jpademo.relationships.entity.Student;
@RunWith(SpringRunner.class)
@SpringBootTest // (webEnvironment = WebEnvironment.RANDOM_PORT)
public class JPQLDemoApplicationTest {
// @LocalServerPort
// String port;
@Autowired
EntityManager entityManager;
@Test
public void basic() {
Query query = entityManager.createQuery("SELECT c FROM Course c");
System.out.println(query.getResultList());
}
@Test
public void basic_typed() {
TypedQuery<Course> query = entityManager.createQuery("SELECT c FROM Course c", Course.class);
List<Course> resultList = query.getResultList();
System.out.println(resultList);
}
@Test
public void basic2() {
Query query = entityManager.createQuery("SELECT c FROM Course c WHERE c.name like '%100 Steps'");
List resultList = query.getResultList();
assertEquals(2, resultList.size());
System.out.println(resultList);
}
@Test
public void basic_empty_courses() {
Query query = entityManager.createQuery("SELECT c FROM Course c WHERE c.students IS EMPTY");
List resultList = query.getResultList();
assertEquals(1, resultList.size());
System.out.println(resultList);
}
@Test
public void basic_courses_with_min_three_students() {
Query query = entityManager.createQuery("SELECT c FROM Course c WHERE size(c.students) >= 3");
List resultList = query.getResultList();
assertEquals(1, resultList.size());
System.out.println(resultList);
}
@Test
public void basic_courses_order_by() {
Query query = entityManager.createQuery("SELECT c FROM Course c ORDER BY size(c.students) DESC");
List resultList = query.getResultList();
assertEquals(3, resultList.size());
System.out.println(resultList);
}
@Test
public void basic3() {
Query query = entityManager.createQuery("SELECT s FROM Student s WHERE s.passport.number like 'N%'");
List resultList = query.getResultList();
assertEquals(1, resultList.size());
System.out.println(resultList);
}
@Test
public void basic4() {
Query query = entityManager.createQuery("SELECT s FROM Student s WHERE s.passport.number like 'N%'");
List resultList = query.getResultList();
assertEquals(1, resultList.size());
System.out.println(resultList);
}
// BETWEEN 100 and 1000
// IS NULL
// upper, lower, trim, length
// Group by, having
@Test
public void join() {
Query query = entityManager.createQuery("SELECT c, s FROM Course c JOIN c.students s");
List resultList = query.getResultList();
System.out.println(resultList.get(1).getClass());
assertEquals(5, resultList.size());
System.out.println(resultList);
}
@Test
public void left_outer_join() {
Query query = entityManager.createQuery("SELECT c, s FROM Course c LEFT JOIN c.students s");
List<Object[]> resultList = query.getResultList();
assertEquals(6, resultList.size());
for (Object[] result : resultList) {
Course course = (Course) result[0];
Student student = (Student) result[1];
System.out.println(course + " " + student);
}
}
@Test
public void cross_join() {
Query query = entityManager.createQuery("SELECT c, s FROM Course c, Student s");
List resultList = query.getResultList();
assertEquals(12, resultList.size());
System.out.println(resultList);
}
}
package com.in28minutes.jpa.jpademo;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
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 com.in28minutes.jpa.jpademo.relationships.entity.Course;
import com.in28minutes.jpa.jpademo.relationships.entity.Student;
@RunWith(SpringRunner.class)
@SpringBootTest // (webEnvironment = WebEnvironment.RANDOM_PORT)
public class NativeQueriesDemoApplicationTest {
// @LocalServerPort
// String port;
@Autowired
EntityManager entityManager;
@Test
public void basic() {
Query query = entityManager.createNativeQuery("SELECT * FROM Course c");
System.out.println(query.getResultList());
}
@Test
public void basic_with_parameter() {
Query query = entityManager.createNativeQuery("SELECT * FROM Course c where c.id = ?");
query.setParameter(1 , 10001L);
List resultList = query.getResultList();
assertEquals(1,resultList.size());
System.out.println(resultList);
}
@Test
public void basic_with_named_parameter() {
Query query = entityManager.createNativeQuery("SELECT * FROM Course c where c.id = :id");
query.setParameter("id", 10001L);
List resultList = query.getResultList();
assertEquals(1,resultList.size());
System.out.println(resultList);
}
@Test
public void basic_with_named_native_query() {
}
@Test
@Transactional
public void updating_a_number_of_rows() {
Query query = entityManager.createNativeQuery("Update Course Set create_date_time=sysdate()");
int executeUpdate = query.executeUpdate();
System.out.println(executeUpdate);
}
@Test
public void basic_typed() {
TypedQuery<Course> query = entityManager.createQuery("SELECT c FROM Course c", Course.class);
List<Course> resultList = query.getResultList();
System.out.println(resultList);
}
@Test
public void basic2() {
Query query = entityManager.createQuery("SELECT c FROM Course c WHERE c.name like '%100 Steps'");
List resultList = query.getResultList();
assertEquals(2, resultList.size());
System.out.println(resultList);
}
@Test
public void basic_empty_courses() {
Query query = entityManager.createQuery("SELECT c FROM Course c WHERE c.students IS EMPTY");
List resultList = query.getResultList();
assertEquals(1, resultList.size());
System.out.println(resultList);
}
@Test
public void basic_courses_with_min_three_students() {
Query query = entityManager.createQuery("SELECT c FROM Course c WHERE size(c.students) >= 3");
List resultList = query.getResultList();
assertEquals(1, resultList.size());
System.out.println(resultList);
}
@Test
public void basic_courses_order_by() {
Query query = entityManager.createQuery("SELECT c FROM Course c ORDER BY size(c.students) DESC");
List resultList = query.getResultList();
assertEquals(3, resultList.size());
System.out.println(resultList);
}
@Test
public void basic3() {
Query query = entityManager.createQuery("SELECT s FROM Student s WHERE s.passport.number like 'N%'");
List resultList = query.getResultList();
assertEquals(1, resultList.size());
System.out.println(resultList);
}
@Test
public void basic4() {
Query query = entityManager.createQuery("SELECT s FROM Student s WHERE s.passport.number like 'N%'");
List resultList = query.getResultList();
assertEquals(1, resultList.size());
System.out.println(resultList);
}
// BETWEEN 100 and 1000
// IS NULL
// upper, lower, trim, length
// Group by, having
@Test
public void join() {
Query query = entityManager.createQuery("SELECT c, s FROM Course c JOIN c.students s");
List resultList = query.getResultList();
System.out.println(resultList.get(1).getClass());
assertEquals(5, resultList.size());
System.out.println(resultList);
}
@Test
public void left_outer_join() {
Query query = entityManager.createQuery("SELECT c, s FROM Course c LEFT JOIN c.students s");
List<Object[]> resultList = query.getResultList();
assertEquals(6, resultList.size());
for (Object[] result : resultList) {
Course course = (Course) result[0];
Student student = (Student) result[1];
System.out.println(course + " " + student);
}
}
@Test
public void cross_join() {
Query query = entityManager.createQuery("SELECT c, s FROM Course c, Student s");
List resultList = query.getResultList();
assertEquals(12, resultList.size());
System.out.println(resultList);
}
}
package com.in28minutes.jpa.jpademo;
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 com.in28minutes.jpa.jpademo.relationships.repository.CourseRepository;
@RunWith(SpringRunner.class)
@SpringBootTest
public class PerformanceDemoApplicationTest {
@Autowired
CourseRepository courseRepository;
@Test
public void testNplus1(){
courseRepository.printAllCourseAndStudents();
//courseRepository.printAllCourseAndStudentsDynamicSubgraph();
//courseRepository.printAllCourseAndStudentsJoinFetch();
}
}
package com.in28minutes.jpa.jpademo;
import static org.junit.Assert.assertNull;
import javax.persistence.EntityManager;
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 com.in28minutes.jpa.jpademo.relationships.entity.Passport;
import com.in28minutes.jpa.jpademo.relationships.repository.TransactionManagementRepository;
@RunWith(SpringRunner.class)
@SpringBootTest // (webEnvironment = WebEnvironment.RANDOM_PORT)
public class TransactionManagementDemoApplicationTests {
@Autowired
TransactionManagementRepository transactionManagementRepository;
@Autowired
EntityManager entityManager;
@Test
public void someTest() {
try {
transactionManagementRepository.doSomething();
} catch (Exception e) { }
assertNull(entityManager.find(Passport.class, 1L));
}
}
insert into passport(id, number)
values(40001, 'L123456');
insert into passport(id, number)
values(40002, 'M123456');
insert into passport(id, number)
values(40003, 'N123456');
insert into passport(id, number)
values(40004, 'O123456');
insert into course(id, name)
values(10001,'Spring in 100 Steps');
insert into course(id, name)
values(10002,'Spring Boot in 100 Steps');
insert into course(id, name)
values(10003,'JPA in 50 Steps');
insert into student(id, name,passport_id)
values(20001, 'Adam',40001);
insert into student(id, name,passport_id)
values(20002, 'Buck',40002);
insert into student(id, name,passport_id)
values(20003, 'Chris',40003);
insert into student(id, name,passport_id)
values(20004, 'Dennis',40004);
insert into course_students(courses_id,students_id)
values(10001,20001);
insert into course_students(courses_id,students_id)
values(10001,20002);
insert into course_students(courses_id,students_id)
values(10001,20003);
insert into course_students(courses_id,students_id)
values(10002,20001);
insert into course_students(courses_id,students_id)
values(10002,20002);