
Introduction to Spring Data Dr. Mark Pollack
Agenda The current data landscape Project Goals Project Tour
Enterprise Data Trends • Unstructured Data • No predefined data model • Often doesn’t fit well in RDBMS • Pre-Aggregated Data • Computed during data collection • Counters • Running Averages
The Value of Data Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9 (KHTML, like Gecko) Safari/419.3 • Value from Data Exceeds Hardware & Software costs • Value in connecting data sets • Grouping e-commerce users by user agent
The Data Revolution • Extremely difficult/impossible to scale writes in RDBMS • Vertical scaling is limited/expensive • Horizontal scaling is limited or requires $$ • Shift from ACID to BASE • Basically Available, Scalable, Eventually Consistent • NoSQL datastores emerge as “point solutions” • Amazon/Google papers • Facebook, LinkedIn …
NoSQL “Not Only SQL” NOSQL \no-seek-wool\ n. Describes ongoing trend where developers increasingly opt for non-relational databases to help solve their problems, in an effort to use the right tool for the right job. • Query Mechanisms: • Key lookup, map-reduce, query-by-example, query language, traversals
Big Data “Big data” refers to datasets whose size is beyond the ability of typical database software tools to capture, store, manage, and analyze. A subjective and moving target. Big data in many sectors today range from 10’s of TB to multiple PB
Spring Data - Background and Motivation • Data access landscape has changed considerably • RDBMS are still important and predominant • but no longer considered a “one size fits all” solution • But they have limitations • Hard to scale • New data access technologies are solving problems RDBMS can’t • Higher performance and scalability, different data models • Often limited transactional model and relaxed consistency • Polyglot persistence is becoming more prevalent • Combine RDBMS + other DBs in a solution
Spring and Data Access • Spring has always provided excellent data access support • Transaction Management • Portable data access exception hierarchy • JDBC – JdbcTemplate • ORM - Hibernate, JPA, JDO, Ibatis support • Cache support (Spring 3.1) • Spring Data project started in 2010 • Goal is to “refresh” Spring’s Data Access support • In light of new data access landscape
Spring Data Mission Statement 89% of all virtualized applications in the world run on VMware. Gartner, December 2008 “ Provides a familiar and consistent Spring-based programming model for Big Data, NoSQL, and relational stores while retaining store-specific features and capabilities.
Spring Data Mission Statement 89% of all virtualized applications in the world run on VMware. Gartner, December 2008 “ Provides a familiar and consistent Spring-based programming model for Big Data, NoSQL, and relational stores while retaining store-specific features and capabilities.
Spring Data Mission Statement 89% of all virtualized applications in the world run on VMware. Gartner, December 2008 “ store-specific features and capabilities.
Spring Data – Supported Technologies • Big Data • Hadoop • HDFS and M/R • Hive • Pig • Cascading • Splunk • Access • Repositories • QueryDSL • REST • Relational • JPA • JDBC Extensions • NoSQL • Redis • HBase • Mongo • Neo4j • Lucene • Gemfire
Spring Data – Have it your way • Shared programming models and data access mechanisms • Repository Model • Common CRUD across data stores • Integration with QueryDSL • Typesafe query language • REST Exporter • Expose repository over HTTP in a RESTful manner. • Database specific features are accessed through familiar Spring Template pattern • RedisTemplate • HBaseTemplate • MongoTemplate • Neo4jTemplate • GemfireTemplate
Spring Data JDBC Extensions – Oracle Support • Easy Access to native XML, Struct, Array data types • API for customizing the connection environment • Fast Connection Failover • Simplified configuration for Advanced Queuing JMS support and DataSource • Single local transaction for messaging and database access
QueryDSL “ Enables the construction of type-safe SQL-like queries for multiple backends including JPA, JDO, MongoDB, Lucence, SQL and plain collections in Java • http://www.querydsl.com/ - Open Source, Apache 2.0
Problems using Strings for a query language Using strings is error-prone Must remember query syntax, domain classes, properties and relationships Verbose parameter binding by name or position Each back-end has its own query language and API Note: .NET has LINQ
QueryDSL Features QCustomer customer = QCustomer.customer; JPQLQuery query = new JPAQuery(entityManger) Customer bob = query.from(customer) .where(customer.firstName.eq(“Bob”) .uniqueResult(customer) • Code completion in IDE • Almost no syntactically invalid queries allowed • Domain types and properties can be references safely (no Strings) • Helper classes generated via Java annotation processor • Much less verbose than JPA2 Criteria API
Using QueryDSL for JDBC QAddress qAddress = QAddress.address; SQLTemplates dialect = new HSQLDBTemplates(); SQLQuery query = new SQLQueryImpl(connection, dialect) .from(qAddress) .where(qAddress.city.eq("London")); List<Address> results = query.list(new QBean<Address>(Address.class, qAddress.street, qAddress.city, qAddress.country)); Querydsl Predicate • Incorporate code-generation into your build process • To create a query meta-model of domain classes or Tables (JDBC) • For SQL
Spring JDBC Extension – QueryDslJdbcTemplate • Wrapper around JdbcTemplate that supports • Using Querydsl SQLQuery classes to execute queries • Integrates with Spring’s transaction management • Automatically detects DB type and set SQLTemplates dialect • Spring RowMapper and ResultSetExtractors for mapping to POJOs • Executing insert, updates and deletes with Querdsl’s SQLInsertClause, SQLUpdateClause, and SQLDeleteClause
Spring JDBC Extension – QueryDslJdbcTemplate // Query with join QCustomer qCustomer = QCustomer.customer; SQLQuery findByIdQuery = qdslTemplate.newSqlQuery() .from(qCustomer) .leftJoin(qCustomer._addressCustomerRef, qAddress) .where(qCustomer.id.eq(id));
Repositories Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects. http://martinfowler.com/eaaCatalog/repository.html
Spring Data Repositories We remove the busy work of developing a repository
For Example… publicinterface CustomerRepository { Customer findOne(Long id); Customer save(Customer customer); Customer findByEmailAddress(EmailAddress emailAddress); } @Entity publicclass Customer { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(unique = true) private EmailAddress emailAddress; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "customer_id") private Set<Address> addresses = new HashSet<Address>(); // constructor, properties, equals, hashcode omitted for brevity }
Traditional JPA Implementation @Repository public class JpaCustomerRepository implements CustomerRepository { @PersistenceContext private EntityManager em; @Override public Customer findOne(Long id) { returnem.find(Customer.class, id); } public Customer save(Customer customer) { if (customer.getId() == null) { em.persist(customer); return customer; } else { returnem.merge(customer); } } ...
Traditional JPA Implementation . . . @Override public Customer findByEmailAddress(EmailAddress emailAddress) { TypedQuery<Customer> query = em.createQuery("select c from Customer c where c.emailAddress = :email", Customer.class); query.setParameter("email", emailAddress); return query.getSingleResult(); } }
Spring Data Repositories • A simple recipe • Map your POJO using JPA • Extend a repository (marker) interface or use an annotation • Add finder methods • Configure Spring to scan for repository interfaces and create implementations • Inject implementations into your services and use as normal…
Spring Data Repository Example publicinterface CustomerRepository extends Repository<Customer, Long> { // Marker Interface Customer findOne(Long id); Customer save(Customer customer); Customer findByEmailAddress(EmailAddress emailAddress); } @RepositoryDefinition(domainClass=Customer.class, idClass=Long.class) publicinterface CustomerRepository { . . . } or
Spring Data Repository Example @Configuration @EnableJpaRepositories @Import(InfrastructureConfig.class) publicclass ApplicationConfig { } <jpa:repositories base-package="com.oreilly.springdata.jpa" /> Boostratp with JavaConfig Or XML And Spring will create an implementation the interface
Spring Data JPA - Usage Wire into your transactional service layer as normal
Query Method Keywords How does findByEmailAddres work…
Spring Data Repositories - CRUD publicinterface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { T save(T entity); Iterable<T> save(Iterable<? extends T> entities); T findOne(ID id); boolean exists(ID id); Iterable<T> findAll(); long count(); void delete(ID id); void delete(T entity); void delete(Iterable<? extends T> entities); void deleteAll(); }
Paging, Sorting, and custom finders publicinterface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort); Page<T> findAll(Pageable pageable); } publicinterfacePersonRepositoryextendsCrudRepository<Person,BigInteger> { // Finder for a single entity Person findByEmailAddress(String emailAddress); // Finder for a multiple entities List<Person> findByLastnameLike(String lastName); // Finder with pagination Page<Person> findByFirstnameLike(String firstName, Pageable page); }
Spring Data JPA – Customize Query Methods publicinterfaceCustomerRepositoryextendsCrudRepository<Customer,Long> { // previous methods omitted… @Query("select p from Person p where p.emailAddress = ?1") Person findByEmailAddress(String emailAddress); @Query("select p from Person p where p.firstname = :firstname or p.lastname = :lastname") Person findByLastnameOrFirstname(@Param("lastname") String lastname, @Param("firstname") String firstname); } • Query methods use method naming conventions • Can override with Query annotation • Or method name references JPA named query
Spring Data JPA – Other features Specifications using JPA Criteria API LockMode, override Transactional metadata, QueryHints Auditing, CDI Integration QueryDSL support
Querydsl and JPA CriteriaBuilder builder = entityManagerFactory.getCriteriaBuilder(); CriteriaQuery<Person> query = builder.createQuery(Person.class); Root<Person> men = query.from( Person.class ); Root<Person> women = query.from( Person.class ); Predicate menRestriction = builder.and( builder.equal( men.get( Person_.gender ), Gender.MALE ), builder.equal( men.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE ) ); Predicate womenRestriction = builder.and( builder.equal( women.get( Person_.gender ), Gender.FEMALE ), builder.equal( women.get( Person_.relationshipStatus ),RelationshipStatus.SINGLE ) ); query.where( builder.and( menRestriction, womenRestriction ) ); • Easier and less verbose and JPA2 Criteria API • “equals property value” vs. “property equals value” • Operations via a builder object
Querydsl and JPA JPAQuery query = new JPAQuery(entityManager); QPerson men = new QPerson("men"); QPerson women = new QPerson("women"); query.from(men, women).where(men.gender.eq(Gender.MALE), men.relationshipStatus.eq(RelationshipStatus.SINGLE), women.gender.eq(Gender.FEMALE), women.relationshipStatus.eq(RelationshipStatus.SINGLE)); Querydsl Predicates verus…
QueryDSL - Repositories publicinterface QueryDSLPredicateExecutor<T> { long count(com.mysema.query.types.Predicate predicate); T findOne(Predicate predicate); List<T> findAll(Predicate predicate); List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders); Page<T> findAll(Predicate predicate, Pageable pageable); } public interface ProductRepository extends Repository<Product,Long>, QueryDslPredicateExecutor<Product> { … } Product iPad = productRepository.findOne(product.name.eq("iPad")); Predicate tablets = product.description.contains("tablet"); Iterable<Product> result = productRepository.findAll(tablets);
Key/Value Familiar, much like a hash table Redis, Riak, Voldemort,… Amazon Dynamo inspired
Column Family • Extended key/value model • values can also be key/value pairs • HBase, Cassandra • Google Bigtable inspired