Spring Data JPA · What is Spring Data JPA? ORM CRUD Query DSL Wednesday, August 21, 13. What is...

98
Spring Data JPA Spring Data Commons Dan Bunker Wednesday, August 21, 13

Transcript of Spring Data JPA · What is Spring Data JPA? ORM CRUD Query DSL Wednesday, August 21, 13. What is...

Spring Data JPASpring Data Commons

Dan Bunker

Wednesday, August 21, 13

Training Overview•Intro to Spring Data JPA

•JPA Repositories•Queries•Paging, Sorting and Auditing

•LDS ServiceProxy to Spring Data JPA

•Labs and Hands on Work

Wednesday, August 21, 13

Prerequisites•Java 6+ and IDE Environment

•Class Provided Pet Store App

•Previous Experience with Spring and JPA

•Part 1, 2 and 3 Spring Training•Introduction to JPA Training

•Previous Oracle Experience and RDBM’s

•Understanding of Maven

Wednesday, August 21, 13

What is Spring Data JPA?

ORM

Wednesday, August 21, 13

What is Spring Data JPA?

ORM

CRUD

Wednesday, August 21, 13

What is Spring Data JPA?

ORM

CRUD

Query DSL

Wednesday, August 21, 13

What is Spring Data JPA?

ORM

CRUD

Query DSL

Auditing

Wednesday, August 21, 13

What is Spring Data JPA?

ORM

CRUD

Query DSL

Auditing

Pagination

Wednesday, August 21, 13

What is Spring Data JPA?

ORM

CRUD

Plug n Play - Fully Customizable

Query DSL

Auditing

Pagination

Wednesday, August 21, 13

Tables

Wednesday, August 21, 13

Entities@Entitypublic class Animal extends AbstractAuditingEntity {! @Id! @SequenceGenerator(name = "AnimalIdSequence", sequenceName = "ANIMAL_ID_SEQ", allocationSize=1)! @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="AnimalIdSequence")! private Long id;

@Length(max=50) @NotEmpty @Column(unique=true, nullable=false) private String name;

...}

Wednesday, August 21, 13

Instead of writing this...public Animal findAnimal (Long animalId) {

return entityManager.find(Animal.class, animalId);}

public void deleteAnimal (Long animalId) { Animal a = entityManager.find(Animal.class, animalId); entityManager.remove(a);}

public Animal saveAnimal (Animal animal) { return entityManager.persist(animal);}

etc.

Wednesday, August 21, 13

why not write this?public interface AnimalRepository

extends CrudRepository<Animal, Long> {

}

Wednesday, August 21, 13

How We Got HereODBC/JDBC

Wednesday, August 21, 13

How We Got HereODBC/JDBC

EJB 1.x/2.x

Wednesday, August 21, 13

How We Got HereODBC/JDBC

EJB 1.x/2.x

Hibernateibatis Apache DB Utils JDO

Wednesday, August 21, 13

How We Got HereODBC/JDBC

EJB 1.x/2.x

Hibernateibatis Apache DB Utils JDO

EJB 3 / JPASpring JDBC

Wednesday, August 21, 13

How We Got HereODBC/JDBC

EJB 1.x/2.x

Hibernateibatis Apache DB Utils JDO

EJB 3 / JPASpring JDBC

Value Add on Services

Spring Batch Spring Data JPAActiveJDBC QueryDSL

?

Wednesday, August 21, 13

Spring Data JPAPros Cons

•Reduces JPA code

•Replaces ServiceProxy

•Paging and Auditing

•Compatible with other Spring Data projects like JDBC, Mongo, Gemfire...

Wednesday, August 21, 13

Spring Data JPAPros Cons

•Reduces JPA code

•Replaces ServiceProxy

•Paging and Auditing

•Compatible with other Spring Data projects like JDBC, Mongo, Gemfire...

•No control over DSL generated queries

•Java is a compiled language

•Still requires entity modeling and an understanding of JPA

Wednesday, August 21, 13

Lab 1Explain what Spring Data JPA does?

Wednesday, August 21, 13

Assignment

Wednesday, August 21, 13

Assignment•Write out what you think Spring Data JPA does and how it could help or hurt a software project using Spring and JPA.

•Send me an email to [email protected] with your response.

Wednesday, August 21, 13

Solution 1Explain what Spring Data JPA does?

Wednesday, August 21, 13

Solution 1

Wednesday, August 21, 13

Solution 1•Spring Data JPA utilizes what JPA already knows about your entity and table relationships to provide off-the-shelf CRUD operations, automatic finder queries, jpa queries and paging support. It can reduce persistence code by handling a large portion of your standard boilerplate queries using a query DSL.

Wednesday, August 21, 13

Enough Theory•stack-thirdparty maven pom version 3.3.1 and higher contains Spring Data JPA

•Enable in your maven pom by adding dependency:

•groupId: org.springframework.data•artifactId: spring-data-jpa

•Add namespace and schema location to spring context.xml

•Enable <jpa:repositories /> tag

Wednesday, August 21, 13

!<dependencies>

...! ! <dependency>! ! ! <groupId>org.springframework.data</groupId>! ! ! <artifactId>spring-data-jpa</artifactId>! ! </dependency>

...! </dependencies>

pom.xml

Wednesday, August 21, 13

xmlns:jpa="http://www.springframework.org/schema/data/jpa"xsi:schemaLocation="http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"

applicationContext.xml

<jpa:repositories base-package="org.lds.stack.petstore.admin.repository" />

Wednesday, August 21, 13

Spring Data JPASpring Data Commons

In Depth

Wednesday, August 21, 13

Services vs Repositories•When writing an application you need to decide:

•Where should my transaction boundaries live?•Where should persistence code go?•Where should actual queries live in the code?

Wednesday, August 21, 13

Services vs Repositories•When writing an application you need to decide:

•Where should my transaction boundaries live?•Where should persistence code go?•Where should actual queries live in the code?

•If you answered “view tier” for any of these questions, you’re probably a manager

Wednesday, August 21, 13

Services vs Repositories•When writing an application you need to decide:

•Where should my transaction boundaries live?•Where should persistence code go?•Where should actual queries live in the code?

•If you answered “view tier” for any of these questions, you’re probably a manager

•Most of these decisions will come down to either the service or persistence tier

Wednesday, August 21, 13

Basic RundownService Tier Persistence Tier

Wednesday, August 21, 13

Basic Rundown

@Service @Repository @Entity

Service Tier Persistence Tier

Wednesday, August 21, 13

Basic Rundown

DashboardService

@Service @Repository @Entity

Service Tier Persistence Tier

Wednesday, August 21, 13

Basic Rundown

DashboardService

@Service @Repository @Entity

Service Tier Persistence Tier

UserRepository

MessageRepository

Wednesday, August 21, 13

Basic Rundown

DashboardService

@Service @Repository @Entity

Service Tier Persistence Tier

UserRepository

MessageRepository

User

Message

Wednesday, August 21, 13

Basic Rundown

DashboardService

@Service @Repository @Entity

Service Tier Persistence Tier

UserRepository

MessageRepository

User

Message

Why add @Repository layer?JDBC, JPA, Mongo, etc. (Impls)

Wednesday, August 21, 13

Basic Rundown

DashboardService

@Service @Repository @Entity

Service Tier Persistence Tier

UserRepository

MessageRepository

User

Message

Why add @Repository layer?JDBC, JPA, Mongo, etc. (Impls)

Typically Tx’s are handled here

Wednesday, August 21, 13

Basic Rundown

DashboardService

@Service @Repository @Entity

Service Tier Persistence Tier

UserRepository

MessageRepository

User

Message

Why add @Repository layer?JDBC, JPA, Mongo, etc. (Impls)

Typically Tx’s are handled here

Dependency Flow

Wednesday, August 21, 13

CrudRepositoryContract from

Spring Data Commons

Wednesday, August 21, 13

CrudRepository

Extension ofSpring Repo Concept

Contract fromSpring Data Commons

Wednesday, August 21, 13

CrudRepository

Extension ofSpring Repo Concept

Domain TypeDomain ID

Contract fromSpring Data Commons

Wednesday, August 21, 13

CrudRepository

Extension ofSpring Repo Concept

Domain TypeDomain ID

•count()•delete(ID id)•delete(Iterable entities)•delete(T entity)•deleteAll()•exists(ID id)•findAll()•findAll(Iterable entities)•findOne(ID id)•save(Iterable entities)•save(S entity)

Contract fromSpring Data Commons

Wednesday, August 21, 13

PagingAndSortingRepositContract from

Spring Data Commons

Wednesday, August 21, 13

PagingAndSortingRepositContract from

Spring Data Commons

PageRequest

Wednesday, August 21, 13

PagingAndSortingRepositContract from

Spring Data Commons

PageRequest

Page

Wednesday, August 21, 13

PagingAndSortingRepositContract from

Spring Data Commons

PageRequest

Page

Extends CrudRepository

•findAll(Pageable request)•findAll(Sort sort)

Wednesday, August 21, 13

JpaRepository

Impl ofSpring Data Commons

Wednesday, August 21, 13

JpaRepository

Impl ofSpring Data Commons

JPA BasedImplementation

Wednesday, August 21, 13

JpaRepository

Impl ofSpring Data Commons

JPA BasedImplementation

ProcessesQuery DSL Statements

Wednesday, August 21, 13

JpaRepository

Impl ofSpring Data Commons

JPA BasedImplementation

•findAll()•findAll(Sort sort)•flush()•save(Iterable entities)•saveAndFlush(T entity)

ProcessesQuery DSL Statements

Wednesday, August 21, 13

JpaRepository

Impl ofSpring Data Commons

JPA BasedImplementation

•findAll()•findAll(Sort sort)•flush()•save(Iterable entities)•saveAndFlush(T entity)

All features from•CrudRepository•PagingAndSortingRepository

ProcessesQuery DSL Statements

Wednesday, August 21, 13

•DSL = Domain Specific Language

•Spring Data JPA DSL are query mappings based off of your Repository contract method names

•findByName(...);•findByNameAndDescription(...);

•The DSL consists of keywords mixed with the column attribute names of the domain

•Queries become more “English’y”

DSL Queries

Wednesday, August 21, 13

DSL KeywordsAnd findByCityAndState where x.city = ? and x.state = ?

Or findByCityOrZip where x.city = ? or x.zip = ?

Between findByCreateDateBetween where x.createDate between ? and ?

LessThan, GreaterThan findBySalaryLessThan where x.salary < ?

True, False findByMemberTrue where x.member = true

After, Before findByStartDateAfter where x.startDate > ?

Containing, StartingWith, EndingWith

findByNameContaining where x.name like ‘%?%’

IsNull, IsNotNull findByNameIsNull where x.name is null

Like, NotLike findByNameLike where x.name like ?

In, NotIn findById(Collection ids) where x.id in ?

OrderBy findByNameOrderByAgeDesc where x.name = ? order by x.age desc

Wednesday, August 21, 13

Lab 2Writing DSL Queries

Wednesday, August 21, 13

Assignment

Wednesday, August 21, 13

Assignment•Create the following queries:

•Find animals that matches text anywhere in the name

•Find animals in a price range

•Find animals by name or description

•Hint: DSL methods go in AnimalRepository

Wednesday, August 21, 13

Solution 2Writing DSL Queries

Wednesday, August 21, 13

Other Query Resolutionorm.xml defined queries

<named-query name="User.findByLastname"> <query>select u from User u where u.lastname = ?1</query></named-query>

Wednesday, August 21, 13

Other Query Resolutionorm.xml defined queries

<named-query name="User.findByLastname"> <query>select u from User u where u.lastname = ?1</query></named-query>

@NamedQuery defined queries@Entity@NamedQuery(name = "User.findByLastname", query = "select u from User u where u.lastname = ?1")

Wednesday, August 21, 13

Other Query Resolutionorm.xml defined queries

<named-query name="User.findByLastname"> <query>select u from User u where u.lastname = ?1</query></named-query>

@NamedQuery defined queries@Entity@NamedQuery(name = "User.findByLastname", query = "select u from User u where u.lastname = ?1")

Spring Data JPA resolves to a matching method namepublic interface UserRepository extends JpaRepository<User, Long> { List<User> findByLastname(String lastname);}

Wednesday, August 21, 13

@Query AnnotationUse @Query to immediately markup your contract methods

public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u where u.firstname like %?1") List<User> findByFirstnameEndsWith(String firstname);}

Wednesday, August 21, 13

@Query AnnotationUse @Query to immediately markup your contract methods

public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u where u.firstname like %?1") List<User> findByFirstnameEndsWith(String firstname);}

Spring Data JPA handles % characters in like clauses

Wednesday, August 21, 13

Native Queries with @Query can run native queries and map back into objects

public interface UserRepository extends JpaRepository<User, Long> {@Query(value = "SELECT FROM USERS WHERE EMAIL_ADDRESS = ?0", nativeQuery = true)

User findByEmailAddress(String emailAddress);}

Wednesday, August 21, 13

Native Queries with @Query can run native queries and map back into objects

public interface UserRepository extends JpaRepository<User, Long> {@Query(value = "SELECT FROM USERS WHERE EMAIL_ADDRESS = ?0", nativeQuery = true)

User findByEmailAddress(String emailAddress);}

Pagination and Dynamic Sorting are not supported when using native queries

Wednesday, August 21, 13

•Method names match Named Queries (xml or annotation)

•Methods annotated with @Query

•Methods parsed with Query DSL and jpaql generated

•Methods are a pass through to custom impl

Query Discovery Order

Wednesday, August 21, 13

Lab 3Add an @Query Method

Wednesday, August 21, 13

Assignment

Wednesday, August 21, 13

Assignment•Create an @Query:

•Find all animals in a particular classification name

•Hint: The Classification model is a @ManyToOne on the Animal model.

Wednesday, August 21, 13

Solution 3Add an @Query Method

Wednesday, August 21, 13

PaginationUse Pageable to get auto-paging on your queries

public interface UserRepository extends JpaRepository<User, Long> { List<User> findByFirstnameContaining(String firstname, Pageable pager);}

Wednesday, August 21, 13

PaginationUse Pageable to get auto-paging on your queries

public interface UserRepository extends JpaRepository<User, Long> { List<User> findByFirstnameContaining(String firstname, Pageable pager);}

PageableArgumentResolver

Wednesday, August 21, 13

PaginationUse Pageable to get auto-paging on your queries

public interface UserRepository extends JpaRepository<User, Long> { List<User> findByFirstnameContaining(String firstname, Pageable pager);}

PageableArgumentResolver new PageRequest(...)

Wednesday, August 21, 13

SortingUse OrderBy to make your queries ordered

public interface UserRepository extends JpaRepository<User, Long> { List<User> findByFirstnameContainingOrderById(String firstname);}

Wednesday, August 21, 13

SortingUse OrderBy to make your queries ordered

public interface UserRepository extends JpaRepository<User, Long> { List<User> findByFirstnameContainingOrderById(String firstname);}

DSL OrderBy

Wednesday, August 21, 13

SortingUse OrderBy to make your queries ordered

public interface UserRepository extends JpaRepository<User, Long> { List<User> findByFirstnameContainingOrderById(String firstname);}

DSL OrderBy Sort Object

Wednesday, August 21, 13

Combining Sorting and

new PageRequest(int page, int size, Sort sort)

Wednesday, August 21, 13

Combining Sorting and

new PageRequest(int page, int size, Sort sort)

Best approach for DSL Queries

Wednesday, August 21, 13

Combining Sorting and

new PageRequest(int page, int size, Sort sort)

Best approach for DSL Queries

Advanced Paging, Sorting and Filtering may need to be hand rolled still or use Criteria Queries

Wednesday, August 21, 13

Lab 4Add a Pageable Query

Wednesday, August 21, 13

Assignment

Wednesday, August 21, 13

Assignment•Update any existing DSL Query to be Pageable

•Hint: Add Pageable as a parameter in your repository. In your test construct a new PageRequest

Wednesday, August 21, 13

Solution 4Add a Pageable Query

Wednesday, August 21, 13

Replacing LDS ServiceProxy with JPA Repositories

Guide

Wednesday, August 21, 13

ServiceProxy to

AnimalProxy

Service

@Service @Repository

Service Tier Persistence Tier

ControllerCode

Presentation Tier

Wednesday, August 21, 13

ServiceProxy to

AnimalProxy

Service

@Service @Repository

Service Tier Persistence Tier

AnimalRepository

ControllerCode

Presentation Tier

Wednesday, August 21, 13

ServiceProxy to

AnimalProxy

Service

@Service @Repository

Service Tier Persistence Tier

AnimalRepository

ControllerCode

Presentation Tier

Wednesday, August 21, 13

ServiceProxy to

AnimalProxy

Service

@Service @Repository

Service Tier Persistence Tier

AnimalRepository

ControllerCode

Presentation Tier

Wednesday, August 21, 13

ServiceProxy to

AnimalProxy

Service

@Service @Repository

Service Tier Persistence Tier

AnimalRepository

ControllerCode

Presentation Tier

Wednesday, August 21, 13

ServiceProxy to

AnimalProxy

Service

@Service @Repository

Service Tier Persistence Tier

AnimalRepository

ControllerCode

AnimalService

Presentation Tier

Wednesday, August 21, 13

ServiceProxy to

AnimalProxy

Service

@Service @Repository

Service Tier Persistence Tier

AnimalRepository

ControllerCode

AnimalService

Presentation Tier

Wednesday, August 21, 13

•Replace Service Proxies with JPA Repositories

•Remove Service Proxy Maven dependency

•Remove Service Proxy *context.xml markup

ServiceProxy Clean Up

Wednesday, August 21, 13

Unsupported OptionsJPA Repositories don’t support embeddable logic tags

$if $endif

Wednesday, August 21, 13

Unsupported OptionsJPA Repositories don’t support embeddable logic tags

$if $endif

Replace with appropriate logic in a plain service class and call needed JPA queries on the repository

Wednesday, August 21, 13

•Keep method names (contracts) the same when moving to repositories from proxies

•@Find(Query) can be converted to @Query with the exception of $if endif$ statements

•Convert the ServiceProxy to a plain Spring service and have it rely on JPA Repositories. This keeps most client code unaware of any kind of change.

Migration Tips

Wednesday, August 21, 13

Wednesday, August 21, 13