Data

Spring Data JPARepository Example

1. Introduction

Spring Data is a part of Spring Framework. It simplifies the data access process for both relational and non-relational databases. Java Persistence API (JPA) is Java’s standard API specification for object-relational mappingSpring Data JPA is a part of Spring Data and it supports Hibernate 5, OpenJPA 2.4, and EclipseLink 2.6.1.

You can also check this tutorial in the following video:

JPA Relations in Spring Boot – video

Spring Data repository significantly reduces the amount of boilerplate code required to implement data access layers for various persistence stores. Spring Data JpaRepository interface extends CrudRepository and provides finder methods out of the box.

In this example, I will demonstrate how to use Spring Data JpaRepository to create, update, delete, and search contact data in a relational database.

2. Technologies Used

The example code in this article was built and run using:

  • Java 1.8.101 (1.8.x will do fine)
  • Maven 3.3.9 (3.3.x will do fine)
  • Eclipse Mars (Any Java IDE would work)
  • Spring data 1.5.10.RELEASE
  • Hibernate 5.0.12.Final
  • H2 1.4.196

3. Spring Boot JPA Project

Spring Boot Starters provides more than 30 starters to ease the dependency management for your project. The easiest way to generate a Spring Boot JPA with Hibernate project is via Spring starter tool with the steps below:

  1. Go to https://start.spring.io/
  2. Select Maven Project with Java and Spring Boot version 1.5.10 and Add both JPA and H2 in the “search for dependencies”
  3. Enter the group name as jcg.zheng.demo and artifact as jpademo
  4. Click the Generate Project button

A maven project will be generated and downloaded to your workstation. Import it into your Eclipse workspace.

3.1 POM

The generated pom.xml includes H2 and spring-boot-starter-data-jpa, which uses Hibernate as the implementation of JPA.

pom.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?xml version="1.0" encoding="UTF-8"?>
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>jcg.zheng.demo</groupId>
    <artifactId>spring-jparepository-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
 
    <name>spring-jparepository-demo</name>
    <description>Demo Spring Data JPA Application</description>
 
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.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>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </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>
        </plugins>
    </build>
</project>

3.2 JPA Demo Application

The generated JpaDemoApplication.java is annotated with @SpringBootApplication. It is equivalent to use  @Configuration@EnableAutoConfiguration, and @ComponentScan with their default attributes.

We will annotate it with @EnableJpaRepositories. It enables Spring to scan the base package and all its sub-packages for any interfaces extending Repository or one of its sub-interfaces. For each interface found, Spring creates the appropriate bean to handle invocation of the query methods.

We will configure several Spring Beans to manage transactions in the H2 datasource.

JpaDemoApplication.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package jcg.zheng.demo.jpademo;
 
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
 
@SpringBootApplication
@EnableJpaRepositories(basePackages = "jcg.zheng.demo.jpademo")
public class JpaDemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(JpaDemoApplication.class, args);
    }
 
    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
    }
 
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter bean = new HibernateJpaVendorAdapter();
        bean.setDatabase(Database.H2);
        bean.setGenerateDdl(true);
        bean.setShowSql(true);
        return bean;
    }
 
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
            JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
        bean.setDataSource(dataSource);
        bean.setJpaVendorAdapter(jpaVendorAdapter);
        bean.setPackagesToScan("jcg.zheng.demo.jpademo");
        return bean;
    }
 
    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }
}

Note: Configure four Spring Beans – dataSource, jpaVendorAdapter, entityManagerFactory, transactionManager to manage the transactions.

4. Domains

In this step, we will create two domains – Contact and ContactNote. Use the JPA annotations to map them to two tables in a database. These two tables have a one-to-many relationship.

4.1 Contact

The Contact entity class is mapped to CONTACT table in the database. All the fields are mapped to columns with the @Column annotation.

Contact.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package jcg.zheng.demo.jpademo.entity;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.persistence.CascadeType;
import javax.persistence.Column;
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.OneToMany;
import javax.persistence.Table;
 
import jcg.zheng.demo.jpademo.type.PhoneType;
 
@Entity
@Table(name = "CONTACT")
public class Contact {
 
    @Id
    @GeneratedValue
    @Column(name = "ID")
    private Long id;
 
    @Column(name = "First_Name")
    private String firstName;
 
    @Column(name = "Last_Name")
    private String lastName;
 
    @Column(name = "Email")
    private String email;
 
    @Column(name = "Phone_Number")
    private String phoneNumber;
 
    @Column(name = "Phone_Type")
    @Enumerated(EnumType.STRING)
    private PhoneType phoneType;
 
    @OneToMany(mappedBy="contact", cascade = CascadeType.ALL, fetch = FetchType.EAGER, targetEntity = Contact_Note.class)
    private List<Contact_Note> notes;
 
    public Contact() {
    }
 
    public Contact(String firstName, String lastName, String email, PhoneType phoneType, String phone) {
 
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.phoneType = phoneType;
        this.phoneNumber = phone;
    }
 
    public Long getId() {
        return 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 getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getPhoneNumber() {
        return phoneNumber;
    }
 
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
 
    public PhoneType getPhoneType() {
        return phoneType;
    }
 
    public void setPhoneType(PhoneType phoneType) {
        this.phoneType = phoneType;
    }
 
    public List<Contact_Note> getNotes() {
        if (this.notes == null) {
            this.notes = new ArrayList<>();
        }
        return this.notes;
    }
    
    public void addNote(Contact_Note note){
        getNotes().add(note);
        note.setContact(this);
    }
 
    public void setNotes(List<Contact_Note> addresses) {
        this.notes = addresses;
    }
 
}

4.2 Contact Note

The Contact_Note entity class is mapped to Contact_Note table in the database. Each contact can have many contact notes.

Contact_Note.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package jcg.zheng.demo.jpademo.entity;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
 
@Entity
public class Contact_Note {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String message;
 
    @ManyToOne
    @JoinColumn(name = "CONTACT_ID")
    private Contact contact;
 
    public Contact_Note() {
        super();
    }
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public Contact getContact() {
        return contact;
    }
 
    public void setContact(Contact contact) {
        this.contact = contact;
    }
 
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
 
}

4.3 Phone Type

Phone type is defined as an enum and is mapped to the Phone_type column in the CONTACT table.

PhoneType.java

1
2
3
4
5
package jcg.zheng.demo.jpademo.type;
 
public enum PhoneType {
    OFFICE, HOME, MOBILE, OTHER;
}

5. ContactRepository

The repository interface must extend Repository and be typed to the domain class and an ID type. In this step, we will annotate ContactRepository with @Repository and extend it from JpaRepository along with the Contact domain and its ID type. It serves two purposes:

  1. By extending JpaRepository we get a bunch of generic CRUD methods to create, update, delete, and find contacts.
  2. It allows Spring to scan the classpath for this interface and create a Spring bean for it.

ContactRepository.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
package jcg.zheng.demo.jpademo.repository;
 
import java.util.List;
 
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
 
import jcg.zheng.demo.jpademo.entity.Contact;
import jcg.zheng.demo.jpademo.type.PhoneType;
 
@Repository
@Transactional
public interface ContactRepository extends JpaRepository<Contact, Long> {
 
    @Query("SELECT con FROM Contact con  WHERE con.phoneType=(:pType) AND con.lastName= (:lName)")
    List<Contact> findByLastNameAndPhoneType(@Param("pType") PhoneType pType, @Param("lName") String lName);
 
}

We will create ContactRepositoryTest which utilizes SpringRunner and @DataJpaTest to demonstrate that ContactRepository can create, update, delete, and find contacts with just a few lines of code.

ContactRepositoryTest.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
package jcg.zheng.demo.jpademo.repository;
 
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
 
import java.util.List;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.junit4.SpringRunner;
 
import jcg.zheng.demo.jpademo.entity.Contact;
import jcg.zheng.demo.jpademo.entity.Contact_Note;
import jcg.zheng.demo.jpademo.type.PhoneType;
 
@RunWith(SpringRunner.class)
@DataJpaTest
public class ContactRepositoryTest {
 
    @Autowired
    private ContactRepository contactRepo;
 
    @Test
    public void it_can_find_the_contact_after_save_it() {
        Contact contact = new Contact("Mary", "Zheng", "test@test.com", PhoneType.HOME, "6365272943");
        Contact_Note note = new Contact_Note();
        note.setMessage("She is a java geek");
        contact.addNote(note); 
        
        contactRepo.save(contact);
        
        List contacts = contactRepo.findAll();
        
        assertEquals(1, contacts.size());
        assertEquals("Mary", contacts.get(0).getFirstName());
        assertEquals("Zheng", contacts.get(0).getLastName());
        assertEquals("test@test.com", contacts.get(0).getEmail());
        assertEquals(PhoneType.HOME, contacts.get(0).getPhoneType());
        assertEquals("6365272943", contacts.get(0).getPhoneNumber());
        assertEquals(1, contacts.get(0).getNotes().size());
        assertEquals("She is a java geek", contacts.get(0).getNotes().get(0).getMessage());
    }
 
    @Test
    public void it_can_delete_the_contact_after_save_it() {
        Contact contact = new Contact("Mary", "Zheng", "test@test.com", PhoneType.HOME, "6365272943");
        Contact_Note note = new Contact_Note();
        note.setMessage("She is a java geek");
        contact.addNote(note);
        
        contactRepo.save(contact);
        
        List foundContacts = contactRepo.findAll();
 
        contactRepo.delete(foundContacts.get(0));
        
        List contacts = contactRepo.findAll();
        assertEquals(0, contacts.size());
 
    }
    
    @Test
    public void it_can_update_the_contact_after_save_it() {
        Contact contact = new Contact("Mary", "Zheng", "test@test.com", PhoneType.HOME, "6365272943");  
        
        contactRepo.save(contact);     
     
        contact.setEmail("mary.zheng@test.com");
        contactRepo.save(contact);
        
        List contacts = contactRepo.findAll();
        assertEquals(1, contacts.size());
        assertEquals("mary.zheng@test.com", contacts.get(0).getEmail());
    }
 
 
    @Test
    public void it_can_find_contacts_by_name_and_type() {
 
        contactRepo.save(new Contact("Mary", "Zheng", "mary.zheng@jcg.org", PhoneType.HOME, "6368168164"));
        contactRepo.save(new Contact("Tom", "Smith", "tom.smith@jcg.org", PhoneType.MOBILE, "(636) 527-2943"));
        contactRepo.save(new Contact("John", "Joe", "john.joe@jcg.org", PhoneType.OFFICE, "(314) 527 2943"));
        contactRepo.save(new Contact("Cindy", "Chang", "cindy.change@jcg.org", PhoneType.OTHER, "404-789-1456"));
 
        List contactsWithZheng = contactRepo.findByLastNameAndPhoneType(PhoneType.HOME, "Zheng");
        
        assertEquals(1, contactsWithZheng.size());
        Contact foundContact = contactsWithZheng.get(0);
        assertEquals("Mary", foundContact.getFirstName());
        assertEquals("Zheng", foundContact.getLastName());
        assertEquals("mary.zheng@jcg.org", foundContact.getEmail());
        assertEquals(PhoneType.HOME, foundContact.getPhoneType());
        assertEquals("6368168164", foundContact.getPhoneNumber());
        assertEquals(0, foundContact.getNotes().size());       
    }
    
    @Test
    public void it_return_null_when_not_found(){
        Contact found = contactRepo.findOne(2L);
        assertNull(found);
    }
 
}

6. Demo Time

Execute the Junit tests to confirm that the ContactRepository is working as expected.

6.1 Save

it_can_find_the_contact_after_save_it output

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2018-03-08 19:21:55.074  INFO 5024 --- [           main] j.z.d.j.r.ContactRepositoryTest          : Starting ContactRepositoryTest on SL2LS431841 with PID 5024 (started by Shu.Shan in C:\MZheng_Java_workspace\Java Code Geek Examples\spring-jparepository-demo)
2018-03-08 19:21:55.076  INFO 5024 --- [           main] j.z.d.j.r.ContactRepositoryTest          : No active profile set, falling back to default profiles: default
2018-03-08 19:21:55.104  INFO 5024 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7671cb68: startup date [Thu Mar 08 19:21:55 CST 2018]; root of context hierarchy
2018-03-08 19:21:55.544  INFO 5024 --- [           main] beddedDataSourceBeanFactoryPostProcessor : Replacing 'dataSource' DataSource bean with embedded version
2018-03-08 19:21:55.545  INFO 5024 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=jpaDemoApplication; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in jcg.zheng.demo.jpademo.JpaDemoApplication] with [Root bean: class [org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
2018-03-08 19:21:56.184  INFO 5024 --- [           main] o.s.j.d.e.EmbeddedDatabaseFactory        : Starting embedded database: url='jdbc:h2:mem:b7b1d620-048e-4b5e-9675-3c3fd4742c3e;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
2018-03-08 19:21:56.703  INFO 5024 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2018-03-08 19:21:56.724  INFO 5024 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
2018-03-08 19:21:56.894  INFO 5024 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
2018-03-08 19:21:56.898  INFO 5024 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2018-03-08 19:21:56.900  INFO 5024 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2018-03-08 19:21:56.985  INFO 5024 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-03-08 19:21:57.211  INFO 5024 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2018-03-08 19:21:57.988  INFO 5024 --- [           main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000228: Running hbm2ddl schema update
2018-03-08 19:21:58.029  INFO 5024 --- [           main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: CONTACT
2018-03-08 19:21:58.030  INFO 5024 --- [           main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: CONTACT
2018-03-08 19:21:58.038  INFO 5024 --- [           main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: Contact_Note
2018-03-08 19:21:58.040  INFO 5024 --- [           main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: Contact_Note
2018-03-08 19:21:58.121  INFO 5024 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2018-03-08 19:21:58.503  INFO 5024 --- [           main] o.h.h.i.QueryTranslatorFactoryInitiator  : HHH000397: Using ASTQueryTranslatorFactory
2018-03-08 19:21:58.975  INFO 5024 --- [           main] j.z.d.j.r.ContactRepositoryTest          : Started ContactRepositoryTest in 4.345 seconds (JVM running for 5.428)
2018-03-08 19:21:59.035  INFO 5024 --- [           main] o.s.t.c.transaction.TransactionContext   : Began transaction (1) for test context [DefaultTestContext@2ea6137 testClass = ContactRepositoryTest, testInstance = jcg.zheng.demo.jpademo.repository.ContactRepositoryTest@400cff1a, testMethod = it_can_find_the_contact_after_save_it@ContactRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@41ee392b testClass = ContactRepositoryTest, locations = '{}', classes = '{class jcg.zheng.demo.jpademo.JpaDemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1e67a849 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1f554b06, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@131276c2, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4d95d2a2, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@d7556ade, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@528931cf], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@65b97f47]; rollback [true]
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: insert into CONTACT (Email, First_Name, Last_Name, Phone_Number, Phone_Type, ID) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into Contact_Note (CONTACT_ID, message, id) values (?, ?, ?)
Hibernate: select contact0_.ID as ID1_0_, contact0_.Email as Email2_0_, contact0_.First_Name as First_Na3_0_, contact0_.Last_Name as Last_Nam4_0_, contact0_.Phone_Number as Phone_Nu5_0_, contact0_.Phone_Type as Phone_Ty6_0_ from CONTACT contact0_
2018-03-08 19:21:59.317  INFO 5024 --- [           main] o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test context [DefaultTestContext@2ea6137 testClass = ContactRepositoryTest, testInstance = jcg.zheng.demo.jpademo.repository.ContactRepositoryTest@400cff1a, testMethod = it_can_find_the_contact_after_save_it@ContactRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@41ee392b testClass = ContactRepositoryTest, locations = '{}', classes = '{class jcg.zheng.demo.jpademo.JpaDemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1e67a849 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1f554b06, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@131276c2, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4d95d2a2, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@d7556ade, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@528931cf], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]].
2018-03-08 19:21:59.329  INFO 5024 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7671cb68: startup date [Thu Mar 08 19:21:55 CST 2018]; root of context hierarchy
2018-03-08 19:21:59.337  INFO 5024 --- [       Thread-2] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
  • Line 28-29: two Insert statements

6.2 Update

it_can_update_the_contact_after_save_it output

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2018-03-08 19:24:43.821  INFO 18416 --- [           main] j.z.d.j.r.ContactRepositoryTest          : Starting ContactRepositoryTest on SL2LS431841 with PID 18416 (started by Shu.Shan in C:\MZheng_Java_workspace\Java Code Geek Examples\spring-jparepository-demo)
2018-03-08 19:24:43.822  INFO 18416 --- [           main] j.z.d.j.r.ContactRepositoryTest          : No active profile set, falling back to default profiles: default
2018-03-08 19:24:43.846  INFO 18416 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7671cb68: startup date [Thu Mar 08 19:24:43 CST 2018]; root of context hierarchy
2018-03-08 19:24:44.327  INFO 18416 --- [           main] beddedDataSourceBeanFactoryPostProcessor : Replacing 'dataSource' DataSource bean with embedded version
2018-03-08 19:24:44.328  INFO 18416 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=jpaDemoApplication; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in jcg.zheng.demo.jpademo.JpaDemoApplication] with [Root bean: class [org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
2018-03-08 19:24:44.992  INFO 18416 --- [           main] o.s.j.d.e.EmbeddedDatabaseFactory        : Starting embedded database: url='jdbc:h2:mem:be0f302a-c332-4e7a-9d25-83126b6dcb66;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
2018-03-08 19:24:45.520  INFO 18416 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2018-03-08 19:24:45.544  INFO 18416 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
2018-03-08 19:24:45.698  INFO 18416 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
2018-03-08 19:24:45.703  INFO 18416 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2018-03-08 19:24:45.705  INFO 18416 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2018-03-08 19:24:45.811  INFO 18416 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-03-08 19:24:46.051  INFO 18416 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2018-03-08 19:24:46.834  INFO 18416 --- [           main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000228: Running hbm2ddl schema update
2018-03-08 19:24:46.868  INFO 18416 --- [           main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: CONTACT
2018-03-08 19:24:46.869  INFO 18416 --- [           main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: CONTACT
2018-03-08 19:24:46.878  INFO 18416 --- [           main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: Contact_Note
2018-03-08 19:24:46.879  INFO 18416 --- [           main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: Contact_Note
2018-03-08 19:24:46.966  INFO 18416 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2018-03-08 19:24:47.286  INFO 18416 --- [           main] o.h.h.i.QueryTranslatorFactoryInitiator  : HHH000397: Using ASTQueryTranslatorFactory
2018-03-08 19:24:47.689  INFO 18416 --- [           main] j.z.d.j.r.ContactRepositoryTest          : Started ContactRepositoryTest in 4.281 seconds (JVM running for 5.307)
2018-03-08 19:24:47.754  INFO 18416 --- [           main] o.s.t.c.transaction.TransactionContext   : Began transaction (1) for test context [DefaultTestContext@2ea6137 testClass = ContactRepositoryTest, testInstance = jcg.zheng.demo.jpademo.repository.ContactRepositoryTest@400cff1a, testMethod = it_can_update_the_contact_after_save_it@ContactRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@41ee392b testClass = ContactRepositoryTest, locations = '{}', classes = '{class jcg.zheng.demo.jpademo.JpaDemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1e67a849 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1f554b06, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@131276c2, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4d95d2a2, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@d7556ade, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@528931cf], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@3c5dbdf8]; rollback [true]
Hibernate: call next value for hibernate_sequence
Hibernate: insert into CONTACT (Email, First_Name, Last_Name, Phone_Number, Phone_Type, ID) values (?, ?, ?, ?, ?, ?)
Hibernate: update CONTACT set Email=?, First_Name=?, Last_Name=?, Phone_Number=?, Phone_Type=? where ID=?
Hibernate: select contact0_.ID as ID1_0_, contact0_.Email as Email2_0_, contact0_.First_Name as First_Na3_0_, contact0_.Last_Name as Last_Nam4_0_, contact0_.Phone_Number as Phone_Nu5_0_, contact0_.Phone_Type as Phone_Ty6_0_ from CONTACT contact0_
2018-03-08 19:24:47.910  INFO 18416 --- [           main] o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test context [DefaultTestContext@2ea6137 testClass = ContactRepositoryTest, testInstance = jcg.zheng.demo.jpademo.repository.ContactRepositoryTest@400cff1a, testMethod = it_can_update_the_contact_after_save_it@ContactRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@41ee392b testClass = ContactRepositoryTest, locations = '{}', classes = '{class jcg.zheng.demo.jpademo.JpaDemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1e67a849 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1f554b06, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@131276c2, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4d95d2a2, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@d7556ade, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@528931cf], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]].
2018-03-08 19:24:47.913  INFO 18416 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7671cb68: startup date [Thu Mar 08 19:24:43 CST 2018]; root of context hierarchy
2018-03-08 19:24:47.916  INFO 18416 --- [       Thread-2] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
  • Line 27: Update statement

6.3 Delete

it_can_delete_the_contact_after_save_it output

01
02
03
04
05
06
07
08
09
10
11
12
13
2018-03-08 19:25:54.514  INFO 13708 --- [           main] j.z.d.j.r.ContactRepositoryTest          : Started ContactRepositoryTest in 4.379 seconds (JVM running for 5.38)
2018-03-08 19:25:54.573  INFO 13708 --- [           main] o.s.t.c.transaction.TransactionContext   : Began transaction (1) for test context [DefaultTestContext@2ea6137 testClass = ContactRepositoryTest, testInstance = jcg.zheng.demo.jpademo.repository.ContactRepositoryTest@400cff1a, testMethod = it_can_delete_the_contact_after_save_it@ContactRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@41ee392b testClass = ContactRepositoryTest, locations = '{}', classes = '{class jcg.zheng.demo.jpademo.JpaDemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1e67a849 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1f554b06, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@131276c2, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4d95d2a2, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@d7556ade, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@528931cf], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@3c5dbdf8]; rollback [true]
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: insert into CONTACT (Email, First_Name, Last_Name, Phone_Number, Phone_Type, ID) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into Contact_Note (CONTACT_ID, message, id) values (?, ?, ?)
Hibernate: select contact0_.ID as ID1_0_, contact0_.Email as Email2_0_, contact0_.First_Name as First_Na3_0_, contact0_.Last_Name as Last_Nam4_0_, contact0_.Phone_Number as Phone_Nu5_0_, contact0_.Phone_Type as Phone_Ty6_0_ from CONTACT contact0_
Hibernate: delete from Contact_Note where id=?
Hibernate: delete from CONTACT where ID=?
Hibernate: select contact0_.ID as ID1_0_, contact0_.Email as Email2_0_, contact0_.First_Name as First_Na3_0_, contact0_.Last_Name as Last_Nam4_0_, contact0_.Phone_Number as Phone_Nu5_0_, contact0_.Phone_Type as Phone_Ty6_0_ from CONTACT contact0_
2018-03-08 19:25:54.778  INFO 13708 --- [           main] o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test context [DefaultTestContext@2ea6137 testClass = ContactRepositoryTest, testInstance = jcg.zheng.demo.jpademo.repository.ContactRepositoryTest@400cff1a, testMethod = it_can_delete_the_contact_after_save_it@ContactRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@41ee392b testClass = ContactRepositoryTest, locations = '{}', classes = '{class jcg.zheng.demo.jpademo.JpaDemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1e67a849 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1f554b06, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@131276c2, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4d95d2a2, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@d7556ade, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@528931cf], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]].
2018-03-08 19:25:54.783  INFO 13708 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7671cb68: startup date [Thu Mar 08 19:25:50 CST 2018]; root of context hierarchy
2018-03-08 19:25:54.785  INFO 13708 --- [       Thread-2] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
  • Line 8-9: two Delete statements

6.4 Find

it_can_find_contacts_by_name_and_type output

01
02
03
04
05
06
07
08
09
10
11
12
13
14
2018-03-08 19:26:42.878  INFO 13712 --- [           main] j.z.d.j.r.ContactRepositoryTest          : Started ContactRepositoryTest in 4.246 seconds (JVM running for 5.266)
2018-03-08 19:26:42.949  INFO 13712 --- [           main] o.s.t.c.transaction.TransactionContext   : Began transaction (1) for test context [DefaultTestContext@2ea6137 testClass = ContactRepositoryTest, testInstance = jcg.zheng.demo.jpademo.repository.ContactRepositoryTest@400cff1a, testMethod = it_can_find_contacts_by_name_and_type@ContactRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@41ee392b testClass = ContactRepositoryTest, locations = '{}', classes = '{class jcg.zheng.demo.jpademo.JpaDemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1e67a849 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1f554b06, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@131276c2, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4d95d2a2, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@d7556ade, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@528931cf], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@3c5dbdf8]; rollback [true]
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: insert into CONTACT (Email, First_Name, Last_Name, Phone_Number, Phone_Type, ID) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into CONTACT (Email, First_Name, Last_Name, Phone_Number, Phone_Type, ID) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into CONTACT (Email, First_Name, Last_Name, Phone_Number, Phone_Type, ID) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into CONTACT (Email, First_Name, Last_Name, Phone_Number, Phone_Type, ID) values (?, ?, ?, ?, ?, ?)
Hibernate: select contact0_.ID as ID1_0_, contact0_.Email as Email2_0_, contact0_.First_Name as First_Na3_0_, contact0_.Last_Name as Last_Nam4_0_, contact0_.Phone_Number as Phone_Nu5_0_, contact0_.Phone_Type as Phone_Ty6_0_ from CONTACT contact0_ where contact0_.Phone_Type=? and contact0_.Last_Name=?
2018-03-08 19:26:43.098  INFO 13712 --- [           main] o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test context [DefaultTestContext@2ea6137 testClass = ContactRepositoryTest, testInstance = jcg.zheng.demo.jpademo.repository.ContactRepositoryTest@400cff1a, testMethod = it_can_find_contacts_by_name_and_type@ContactRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@41ee392b testClass = ContactRepositoryTest, locations = '{}', classes = '{class jcg.zheng.demo.jpademo.JpaDemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1e67a849 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1f554b06, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@131276c2, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4d95d2a2, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@d7556ade, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@528931cf], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]].
2018-03-08 19:26:43.103  INFO 13712 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7671cb68: startup date [Thu Mar 08 19:26:39 CST 2018]; root of context hierarchy
2018-03-08 19:26:43.105  INFO 13712 --- [       Thread-2] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
  • Line 11: Select statements

7. Spring Data JPARepository – Summary

In this example, we built a Spring Boot project to demonstrate how easy it is to configure and use Spring data JpaRepository to manage the data in the database.

Spring Data JPA provides an abstraction to the persistence layer and has a common API. All you have to do is to implement a Repository interface, declare the repository methods and annotate the methods with @Query that should be executed.

However, There are some pitfalls when using JPA. Please check here for detail.

8. Download the Source Code

This example consists of a Spring Boot JPA project.

Download
You can download the full source code of this example here: Spring Data JpaRepository Example

Mary Zheng

Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Abderraouf Makhlouf
Abderraouf Makhlouf
6 years ago

In spring boot you don’t need to define: jpaVendorAdapter, entityManagerFactory,transactionManager

Just you need to have application.properties with this key values :

application.properties

# database configuration
spring.datasource.url=jdbc:h2:file:~/main-source;AUTO_SERVER=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver

Bhaskar
Bhaskar
3 years ago

What will be table structure for both table ?

Back to top button