Spring Data JPA · What is Spring Data JPA? ORM CRUD Query DSL Wednesday, August 21, 13. What is...
Transcript of Spring Data JPA · What is Spring Data JPA? ORM CRUD Query DSL Wednesday, August 21, 13. What is...
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
CRUD
Plug n Play - Fully Customizable
Query DSL
Auditing
Pagination
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
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
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 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
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 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
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
PageRequest
Page
Extends CrudRepository
•findAll(Pageable request)•findAll(Sort sort)
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
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
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
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
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)
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
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
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