SlideShare una empresa de Scribd logo
1 de 23
M.C. Kang
   Overview
                                                                Spring Data is a high level
                                                               SpringSource project whose purpose is to
                                                               unify and ease the access to different
                                                               kinds of persistence stores, both
                                                               relational database systems and NoSQL
                                                               data stores.




      Source http://www.infoq.com/articles/spring-data-intro




Spring Data projects support the followings aspects:
Templating
Object/Datastore mapping
Repository support
   Overview - Templates
  The main purpose of a Spring Data template (and all other Spring templates) is resource
  allocation and exception translation.


  A template offers store specific operations like saving, updating and deleting a single
  record or for executing queries or map/reduce jobs. But all these methods work only for the
  corresponding underlying datastore.




MongoDb Template Configuration Example
<!-- Connection to MongoDB server -->
<mongo:db-factory host="localhost" port="27017" dbname="test" />
<!-- MongoDB Template -->
<bean id="mongoTemplate“
class="org.springframework.data.mongodb.core.MongoTemplate">
          <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>
     Overview - Object/Datastore Mapping
    With Spring Data, this support is extended to NoSQL datastores with object-like data structures. But
    these data structures can be quite different from each other, so it would be difficult to
    make up a common API for object/datastore mapping. Each type of datastore comes with its own set of
    annotations to provide the needed meta information for the mapping.




                       JPA                                                MongoDB                                           Neo4j
@Entity                                                  @Document( collection="usr")                      @NodeEntity
@Table(name="TUSR")                                      public class User {                               public class User {   
public class User {                                               @Id   private String id;                         @GraphId   Long id;  
          @Id    private String id;                               @Field("fn")   private String name;               private String name;   
          @Column(name="fn")   private String name;               private Date lastLogin;                          private Date lastLogin;
          private Date lastLogin;                                   ...                                            ...
          ...                                             }                                                }
}
   Overview - Repository Support
generic support for CRUD and paging , sorting by providing special parameters to the finder
methods for all persistence stores


The main advantages of repository support are:
     The developer writes a lot less boilerplate code
     Queries can by defined alongside the finder method and its documentation
     As a bonus, the JPQL queries are compiled as soon as the Spring context is assembled,
     not the first time you use the query, which makes it easier to detect syntax errors
    Data Model                                 Domain Model

    Customer                       Address


                                                        <<MappedSuperClass>>
                                                              AbstractEntity

CREATE TABLE customer (
 id BIGINT IDENTITY PRIMARY KEY,
 firstname VARCHAR(255),
 lastname VARCHAR(255),
 email_address VARCHAR(255));
                                                               <<Entity>>
CREATE UNIQUE INDEX ix_customer_email                           Customer
ON CUSTOMER (email_address ASC);

CREATE TABLE address (
 id BIGINT IDENTITY PRIMARY KEY,
 customer_id BIGINT CONSTRAINT
address_customer_ref REFERENCES
customer (id),
 street VARCHAR(255),
 city VARCHAR(255),                              <<Entity>>            <<Embeddable>>
 country VARCHAR(255));
                                                  Address                  EmailAddress




                         Step1. “Define Domain Model”
    AbstractEntity                                                        Customer
@M appedSupercl ass                                                @Entity
public class AbstractEntity {                                      public class Customer extends AbstractEntity {

          @Id                                                               private String firstname, lastname;
          @GeneratedValue(strategy = GenerationT ype. AUTO)
          private Long id;                                                  @Col umn(unique = true)
                                                                            private EmailAddress emailAddress;
          public Long getId() {
                    return id;                                              @OneToMany(cascade = CascadeType.ALL, orphanRemoval =
          }                                                                 true)
                                                                            @JoinColumn(nam e = "custom er_id")
          public boolean equals(Object obj) {                               private Set<Address> addresses = new HashSet<Address>();
                    if (this == obj) {
                    return true;                                            public Customer(String firstname, String lastname) {
                    }
                                                                                      Assert.hasText(firstname);
                     if (this.id == null || obj == null || !                          Assert.hasText(lastname);
                     (this.getClass().equals(obj.getClass()))) {
                                              return false;                           this.firstname = firstname;
                     }                                                                this.lastname = lastname;
                                                                            }
                     AbstractEntity that = (AbstractEntity) obj;
                                                                            protected Customer() {
                     return this.id.equals(that.getId());
          }                                                                 }

          public int hashCode() {                                           public void add(Address address) {
                     return id == null ? 0 : id.hashCode();
          }                                                                           Assert.notNull(address);
}                                                                                     this.addresses.add(address);
                                                                            }
                                                                            …
    @MappedSuperclass to express that it is not a                      If there were demand to customize the names of the
    managed                                                            columns to which the properties would be persisted,
    entity class on its own but rather will be extended                you could use the @Column annotation.
    by entity classes.




                                                   Step1. “Define Domain Model”
   Address                                                                  CustomerRepository
@Entity                                                                          public interface CustomerRepository
public class Address extends AbstractEntity {                                                         ext ends CrudRepos itory<Customer, Long> {
                                                                                            Customer findByEmailAddress(EmailAddress emailAddress);
private String street, city, country;                                                       Customer findById(Long id);
                                                                                            List<Customer> findAll();
public Address(String street, String city, String country) {                     }

            Assert.hasText(street, "Street must not be null or empty!");
            Assert.hasText(city, "City must not be null or empty!");
            Assert.hasText(country, "Country must not be null or empty!");

            this.street = street;
            this.city = city;
            this.country = country;
                                                                                            Step2. “Define Repository
}                                                                                                   Interface”
protected Address() {
                                                                                               -Just only interface
}
    …


           EmailAddress
@Em beddabl e
public class EmailAddress {

@Colum n(nam e = "email_address")
private String value;

public EmailAddress(String emailAddress) {
         Assert.isTrue(isValid(emailAddress), "Invalid email address!");
         this.value = emailAddress;
}
                                                                             the EmailAddress class is an @Embeddable, which
protected EmailAddress() {                                                   will cause the persistence provider to flatten out
                                                                             all properties of it into the table of the
}
…                                                                            surrounding class.


        Step1. “Define Domain Model”
    SpringConfig
@Configuration
@EnableT ransactionManagement
@ComponentS can
@EnableJ paReposi tories
public class InfrastructureConfig {

@Bean
public DataSource dataSource() {
          return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("classpath:sql/schema.sql")
          .addScript("classpath:sql/test-data.sql").build();
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
          HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
          vendorAdapter.setDatabase(Database.HSQL);
          //vendorAdapter.setGenerateDdl(true);
          vendorAdapter.setShowSql(true);
          LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
          factory.setJpaVendorAdapter(vendorAdapter);
          factory.setPackagesToScan(getClass().getPackage().getName());
          factory.setDataSource(dataSource());
          return factory;
}

@Bean
public PlatformTransactionManager transactionManager() {
          JpaTransactionManager txManager = new JpaTransactionManager();
          txManager.setEntityManagerFactory(entityManagerFactory().getObject());
          return txManager;
}
}




                                        Step3. “Configure Spring Beans”
     TestCase
@RunWit h(SpringJUnit4Cl assRunner.class)                                               @Test
@Cont extConfiguration(classes = { TestConfig.cl ass })                                 public void saveNewCustomer() {
@T ransactional                                                                         Customer c = new Customer();
@Di rtiesContext                                                                        //c.setFirstname("Sven");
public class TestMain {                                                                 c.setLastname("Svensson");
                                                                                        c.setEmailAddress(new EmailAddress("sven@svensson.org"));
@A utowired                                                                             Address a = new Address("Storgaten 6", "Trosa", "Sweden");
CustomerRepository repository;                                                          c.add(a);
                                                                                        repository.save(c);
@Autowired                                                                              System.out.println(repository.findAll());
DataSource dataSource;                                                                  Customer result = repository.findOne(c.getId());
                                                                                        assertThat(result, is(notNullValue()));
@Test                                                                                   //assertThat(result.getFirstName(), is("Sven"));
public void testFindAll() {                                                             assertThat(result.getEmailAddress().toString(), is(notNullValue()));
List< Custom er> results = reposi tory.findAl l();                                      }
assertThat(results, is(notNullValue()));
assertThat(results, hasSize(3));
assertThat(results.get(0), notNullValue());                                             @Test(expected = DataIntegrityViolationException.class)
assertThat(results.get(1), notNullValue());                                             public void saveNewCustomerWithDuplicateEmail() {
assertThat(results.get(2), notNullValue());                                             Customer c = new Customer("Bob","Doe");
}                                                                                       c.setEmailAddress(new EmailAddress("bob@doe.com"));
                                                                                        Address a = new Address("66 Main St", "Middletown", "USA");
@Test                                                                                   c.add(a);
public void testFindById() {                                                            repository.save(c);
Customer res ult = repository.findOne(100L);                                            }
assertThat(result, is(notNullValue()));
assertThat(result.getFirstname(), is("John"));                                      @Test
}                                                                                   public void deleteCustomer() {
                                                                                    Customer c = repository.findOne(100L);
@Test                                                                               repository.delete(c);
public void testFindByEmail() {                                                     Customer result = repository.findOne(100L);
                                                                                    assertThat(result, is(nullValue()));
Customer result = repository.fi ndByEm ail Address(new EmailA ddress("bob@doe.com"));
assertThat(result, is(notNullValue()));                                             }
assertThat(result.getFirstname(), is("Bob"));
}                                                                                   }




                                                          Step4. “Test it…”
   Document Model                              Domain Model

                   Customer

        Email                 (*)Address
                                                              AbstractDocument


{
  firstname : "Dave",
  lastname : "Matthews",
  email : {
             email : "dave@dmband.com"
                                                               <<Document>>
            },
  addresses : [                                                  Customer
                    {
                      street : "Broadway",
                      city : "New York",
                      country : "United
States"
                    }
                  ]
}
                                                 <<Entity>>             <<Embeddable>>
                                                  Address                   EmailAddress




                           Step1. “Define Domain Model”
     AbstractDocument                                                        Customer
public class AbstractDocument {                                      @Document
                                                                     public class Customer extends AbstractDocument {
         @Id
         private BigInteger id;                                               private String firstname, lastname;

         public BigInteger getId() {                                          @Fi eld("em ail ")
                   return id;                                                 @Indexed(unique = true)
         }                                                                    private EmailAddress emailAddress;
                                                                              private Set<Address> addresses = new HashSet<Address>();
         public boolean equals(Object obj) {
                                                                              public Customer(String firstname, String lastname) {
                   if (this == obj) {
                   return true;                                               Assert.hasText(firstname);
                   }                                                          Assert.hasText(lastname);

                   if (this.id == null || obj == null || !                    this.firstname = firstname;
                   (this.getClass().equals(obj.getClass()))) {                this.lastname = lastname;
                   return false;                                              }
                   }
                                                                              protected Customer() {
                   AbstractDocument that = (AbstractDocument) obj;
                                                                              }
                   return this.id.equals(that.getId());                       …
         }

         public int hashCode() {
                    return id == null ? 0 : id.hashCode();
         }
}




                                                 Step1. “Define Domain Model”
   Address                                                                       CustomerRepository
public class Address {                                                                public interface CustomerRepository
                                                                                                           ext ends CrudRepos itory<Customer, Long> {
            private final String street, city, country;                                          Customer findByEmailAddress(EmailAddress emailAddress);
                                                                                                 Customer findById(Long id);
            public Address(String street, String city, String country) {                         List<Customer> findAll();
                                                                                      }
                       Assert.hasText(street, "Street must not be null or empty!");
                       Assert.hasText(city, "City must not be null or empty!");
                       Assert.hasText(country, "Country must not be null or
                       empty!");

                       this.street = street;
                       this.city = city;
                       this.country = country;
                                                                                                 Step2. “Define Repository
 …
            }                                                                                            Interface”
                                                                                                    -Just only interface

           EmailAddress
public class EmailAddress {

@F iel d("emai l")
private final String value;

public EmailAddress(String emailAddress) {
         Assert.isTrue(isValid(emailAddress), "Invalid email address!");
         this.value = emailAddress;
}

protected EmailAddress() {

}
…




        Step1. “Define Domain Model”
   SpringConfig
@Configuration
@ComponentS can
@EnableM ongoRepositories(baseP ackages="com.mck ang.springdata.mongo")
class ApplicationConfig extends AbstractMongoConfiguration {

       @Autowired
       private List<Converter<?, ?>> converters;

       protected String getDatabaseName() {
                 return "e-store";
       }

       public Mongo mongo() throws Exception {

                Mongo mongo = new Mongo("127.0.0.1");
                mongo.setWriteConcern(WriteConcern.FSYNC_SAFE);

                return mongo;
       }

       public CustomConversions customConversions() {
                 return new CustomConversions(converters);
       }

       protected String get MappingBasePackage () {
                 return "com.mckang.springdata.mongo";
       }
}




                                      Step3. “Configure Spring Beans”
     TestCase
@RunWith(S pringJUnit4ClassRunner.class )                                                  @Test
@ContextConfigurati on(cl asses = { T es tConfi g.class })                                 public void saveNewCustomer() {
@T ransactional                                                                                       Customer c = new Customer();
@DirtiesContext                                                                                       //c.setFirstname("Sven");
public class TestMain {                                                                               c.setLastname("Svensson");
                                                                                                      c.setEmailAddress(new EmailAddress("sven@svensson.org"));
@Autowi red                                                                                           Address a = new Address("Storgaten 6", "Trosa", "Sweden");
Custom erRepository reposi tory;                                                                      c.add(a);
                                                                                                      repository.save(c);
@Autowired                                                                                 }
DataSource dataSource;

@Test                                                                                      @Test(expected = DataIntegrityViolationException.class)
public void testFindAll() {                                                                public void saveNewCustomerWithDuplicateEmail() {
           List<Custom er> results = repository.f indAll ();                                          Customer c = new Customer("Bob","Doe");
           assertThat(results, is(notNullValue()));                                                   c.setEmailAddress(new EmailAddress("bob@doe.com"));
           assertThat(results, hasSize(3));                                                           Address a = new Address("66 Main St", "Middletown", "USA");
           assertThat(results.get(0), notNullValue());                                                c.add(a);
           assertThat(results.get(1), notNullValue());                                                repository.save(c);
           assertThat(results.get(2), notNullValue());                                     }
}
                                                                                           @Test
@Test                                                                                      public void deleteCustomer() {
public void testFindById() {                                                                          Customer c = repository.findOne(100L);
           Custom er result = repos it ory.findOne(100L);                                             repository.delete(c);
           assertThat(result, is(notNullValue()));                                         }
           assertThat(result.getFirstname(), is("John"));
}                                                                                          }

@Test
public void testFindByEmail() {
         Customer result = repository.f indByEm ai lAddres s(new Em ail Address("bob@doe.com"));
}




                                                               Step4. “Test it…”
                                                                (Need Fixture…)
   Graph Database




Neo4j is the leading implementation of a property graph database. It is written
predominantly in Java and leverages a custom storage format and the facilities of the Java
Transaction Architecture (JTA) to provide XA transactions.
Neo4j integrates a transactional, pluggable indexing subsystem that uses Lucene as the
default. The index is used primarily to locate starting points for traversals. Its second use
is to support unique entity creation.
   Cypher statement




With the declarative Cypher query language, Neo4j makes it easier to get started for
everyone who knows SQL from working with relational databases.
enabling users to define sophisticated queries like “find me all the customers who have
friends who have recently bought similar products.”
Like other query languages, it supports filtering, grouping, and paging. Cypher allows easy
creation, deletion, update, and graph construction.
   Graph Model                          Domain Model



                                                      AbstractEntity
                   Customer



                Address
                                                      <<NodeEntity>>
                                                          Customer


      Address



                                         <<NodeEntity>>
                                                                     EmailAddress
                                            Address




                   Step1. “Define Domain Model”
      AbstractDocument                                                        Customer
public abstract class AbstractEntity {                               @NodeEnti ty
                                                                     public class Customer extends AbstractEntity {
          @GraphId
          private Long id;                                                    private String firstName, lastName;

          public Long getId() {                                               @Indexed(unique = true)
                    return id;                                                private String emailAddress;
          }
                                                                              @Rel atedT o(type = "ADDRESS")
          @Override                                                           private Set<Address> addresses = new HashSet<Address>();
          public boolean equals(Object obj) {
                                                                              public Customer(String firstName, String lastName, String emailAddress) {
                     if (this == obj) {
                                           return true;                             Assert.hasText(firstName);
                     }                                                              Assert.hasText(lastName);
                                                                                    Assert.hasText(emailAddress);
                     if (id == null || obj == null || !
                     getClass().equals(obj.getClass())) {                          this.firstName = firstName;
                              return false;                                        this.lastName = lastName;
                     }                                                             this.emailAddress = emailAddress;
                      return id.equals(((AbstractEntity) obj).id);            }

             }                                                                protected Customer() {

          @Override                                                           }
          public int hashCode() {                                             …
                     return id == null ? 0 : id.hashCode();
          }
}




                                                   Step1. “Define Domain Model”
   Address                                                            CustomerRepository
@NodeEntity                                                                public interface CustomerRepository extends GraphRepository<Customer> {
public class Address extends AbstractEntity {
                                                                                   Customer findOne(Long id);
            private String street, city;
                                                                                   <C extends Customer> C save(C customer);

            public Address(String street, String city) {                           Customer findByEmailAddress(String emailAddress);
                      this.street = street;                                }
                      this.city = city;
             }

            public Address() {

            }
                                                                                     Step2. “Define Repository
 …                                                                                           Interface”
                                                                                        -Just only interface

           EmailAddress
public class EmailAddress {

private final String value;

public EmailAddress(String emailAddress) {
         Assert.isTrue(isValid(emailAddress), "Invalid email address!");
         this.value = emailAddress;
}

protected EmailAddress() {

}
…




        Step1. “Define Domain Model”
    SpringConfig
@Configuration
@ComponentS can
@ImportResource("cl asspath:ME TA-INF /spring/spring-data-context.xml ")
@EnableT ransactionManagement
class ApplicationConfig {

           @Bean(destroyMethod = "shutdown")
           public GraphDatabaseService graphDatabaseService() {
                     //return new EmbeddedGraphDatabase("target/graph.db");
                     return new SpringRestGraphDatabase("http://localhost:7474/db/data");
           }
}



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd">


           <!--neo4j:config storeDi rectory="target/graph.db" /-->
           <neo4j :c onfig graphDatabaseService= "graphDatabaseService" />
           <neo4j :repositori es base-package="com. mckang.springdata.neo4j" />
</beans>




                                          Step3. “Configure Spring Beans”
     TestCase
@RunWith(SpringJUni t4ClassRunner.cl ass)
@Context Confi guration(classes = { TestConfig.class })                      @Test
public class TestMain {                                                      public void preventsDuplicateEmail() {

@Autowired                                                                        final EmailAddress email = new EmailAddress("dave@dmband.com");
CustomerReposi tory repository;                                                   Customer dave = repository.findByEmailAddress(email.getEmail());
                                                                                  Customer anotherDave = new Customer("Dave", "Matthews",dave.getEmailAddress());
@Autowired                                                                        repository.save(anotherDave);
DataSource dataSource;                                                       }

@Test                                                                        }
public void savesCustomerCorrectly() {

EmailAddress email = new EmailAddress("alicia@keys.com");
Customer alicia = new Customer("Alicia", "Keys",email.getEmail()); // todo
alicia.add(new Address("27 Broadway", "New York"));
Customer result = repository.save(alicia);
assertThat(result.getId(), is(notNullValue()));
}

@Test
public void readsCustomerByEmail() {

EmailAddress email = new EmailAddress("alicia@keys.com");
Customer alicia = new Customer("Alicia", "Keys",email.getEmail());
repository.save(alicia);
Customer result = repository.findByEmailAddress(email.getEmail());
assertThat(result, is(alicia));
}




                                                           Step4. “Test it…”
                                                            (Need Fixture…)

Más contenido relacionado

La actualidad más candente

Java script objects 1
Java script objects 1Java script objects 1
Java script objects 1H K
 
Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2won min jang
 
Erlang for data ops
Erlang for data opsErlang for data ops
Erlang for data opsmnacos
 
Indexing & Query Optimization
Indexing & Query OptimizationIndexing & Query Optimization
Indexing & Query OptimizationMongoDB
 
Indexing and Query Optimization
Indexing and Query OptimizationIndexing and Query Optimization
Indexing and Query OptimizationMongoDB
 
GPars (Groovy Parallel Systems)
GPars (Groovy Parallel Systems)GPars (Groovy Parallel Systems)
GPars (Groovy Parallel Systems)Gagan Agrawal
 
Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Jesper Kamstrup Linnet
 
concurrency with GPars
concurrency with GParsconcurrency with GPars
concurrency with GParsPaul King
 
concurrency gpars
concurrency gparsconcurrency gpars
concurrency gparsPaul King
 
JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011Stephen Chin
 
BASTA 2013: Custom OData Provider
BASTA 2013: Custom OData ProviderBASTA 2013: Custom OData Provider
BASTA 2013: Custom OData ProviderRainer Stropek
 

La actualidad más candente (20)

Java script objects 1
Java script objects 1Java script objects 1
Java script objects 1
 
Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2
 
Erlang for data ops
Erlang for data opsErlang for data ops
Erlang for data ops
 
Scala - en bedre Java?
Scala - en bedre Java?Scala - en bedre Java?
Scala - en bedre Java?
 
Indexing & Query Optimization
Indexing & Query OptimizationIndexing & Query Optimization
Indexing & Query Optimization
 
Introduction to hibernate
Introduction to hibernateIntroduction to hibernate
Introduction to hibernate
 
Indexing and Query Optimization
Indexing and Query OptimizationIndexing and Query Optimization
Indexing and Query Optimization
 
GPars (Groovy Parallel Systems)
GPars (Groovy Parallel Systems)GPars (Groovy Parallel Systems)
GPars (Groovy Parallel Systems)
 
Lodash js
Lodash jsLodash js
Lodash js
 
Xtext Eclipse Con
Xtext Eclipse ConXtext Eclipse Con
Xtext Eclipse Con
 
Hack reduce mr-intro
Hack reduce mr-introHack reduce mr-intro
Hack reduce mr-intro
 
Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?Scala - en bedre og mere effektiv Java?
Scala - en bedre og mere effektiv Java?
 
concurrency with GPars
concurrency with GParsconcurrency with GPars
concurrency with GPars
 
concurrency gpars
concurrency gparsconcurrency gpars
concurrency gpars
 
Python dictionaries
Python dictionariesPython dictionaries
Python dictionaries
 
Plc (1)
Plc (1)Plc (1)
Plc (1)
 
JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011
 
Plc (1)
Plc (1)Plc (1)
Plc (1)
 
Functional es6
Functional es6Functional es6
Functional es6
 
BASTA 2013: Custom OData Provider
BASTA 2013: Custom OData ProviderBASTA 2013: Custom OData Provider
BASTA 2013: Custom OData Provider
 

Similar a Spring data

High performance JPA with Oracle Coherence
High performance JPA with Oracle CoherenceHigh performance JPA with Oracle Coherence
High performance JPA with Oracle CoherenceMarkus Eisele
 
Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Oliver Gierke
 
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit XtextDomänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit XtextDr. Jan Köhnlein
 
Implementing CQRS and Event Sourcing with RavenDB
Implementing CQRS and Event Sourcing with RavenDBImplementing CQRS and Event Sourcing with RavenDB
Implementing CQRS and Event Sourcing with RavenDBOren Eini
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring DataOliver Gierke
 
Spring data ii
Spring data iiSpring data ii
Spring data ii명철 강
 
NET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptxNET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptxpetabridge
 
Hadoop Integration in Cassandra
Hadoop Integration in CassandraHadoop Integration in Cassandra
Hadoop Integration in CassandraJairam Chandar
 
JakartaData-JCon.pptx
JakartaData-JCon.pptxJakartaData-JCon.pptx
JakartaData-JCon.pptxEmilyJiang23
 
New Features of JSR 317 (JPA 2.0)
New Features of JSR 317 (JPA 2.0)New Features of JSR 317 (JPA 2.0)
New Features of JSR 317 (JPA 2.0)Markus Eisele
 
Uncommon Design Patterns
Uncommon Design PatternsUncommon Design Patterns
Uncommon Design PatternsStefano Fago
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpaStaples
 
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp KrennPaintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp KrennJavaDayUA
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Wed 1630 greene_robert_color
Wed 1630 greene_robert_colorWed 1630 greene_robert_color
Wed 1630 greene_robert_colorDATAVERSITY
 
APIdays Paris 2018 - Building scalable, type-safe GraphQL servers from scratc...
APIdays Paris 2018 - Building scalable, type-safe GraphQL servers from scratc...APIdays Paris 2018 - Building scalable, type-safe GraphQL servers from scratc...
APIdays Paris 2018 - Building scalable, type-safe GraphQL servers from scratc...apidays
 

Similar a Spring data (20)

High performance JPA with Oracle Coherence
High performance JPA with Oracle CoherenceHigh performance JPA with Oracle Coherence
High performance JPA with Oracle Coherence
 
Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!
 
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit XtextDomänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit Xtext
 
iOS Session-2
iOS Session-2iOS Session-2
iOS Session-2
 
Implementing CQRS and Event Sourcing with RavenDB
Implementing CQRS and Event Sourcing with RavenDBImplementing CQRS and Event Sourcing with RavenDB
Implementing CQRS and Event Sourcing with RavenDB
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring Data
 
Kick Start Jpa
Kick Start JpaKick Start Jpa
Kick Start Jpa
 
Spring data ii
Spring data iiSpring data ii
Spring data ii
 
NET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptxNET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptx
 
Hadoop Integration in Cassandra
Hadoop Integration in CassandraHadoop Integration in Cassandra
Hadoop Integration in Cassandra
 
JakartaData-JCon.pptx
JakartaData-JCon.pptxJakartaData-JCon.pptx
JakartaData-JCon.pptx
 
New Features of JSR 317 (JPA 2.0)
New Features of JSR 317 (JPA 2.0)New Features of JSR 317 (JPA 2.0)
New Features of JSR 317 (JPA 2.0)
 
WebDSL
WebDSLWebDSL
WebDSL
 
Uncommon Design Patterns
Uncommon Design PatternsUncommon Design Patterns
Uncommon Design Patterns
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpa
 
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp KrennPaintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Wed 1630 greene_robert_color
Wed 1630 greene_robert_colorWed 1630 greene_robert_color
Wed 1630 greene_robert_color
 
Understanding linq
Understanding linqUnderstanding linq
Understanding linq
 
APIdays Paris 2018 - Building scalable, type-safe GraphQL servers from scratc...
APIdays Paris 2018 - Building scalable, type-safe GraphQL servers from scratc...APIdays Paris 2018 - Building scalable, type-safe GraphQL servers from scratc...
APIdays Paris 2018 - Building scalable, type-safe GraphQL servers from scratc...
 

Último

ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 

Último (20)

ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 

Spring data

  • 2. Overview  Spring Data is a high level SpringSource project whose purpose is to unify and ease the access to different kinds of persistence stores, both relational database systems and NoSQL data stores. Source http://www.infoq.com/articles/spring-data-intro Spring Data projects support the followings aspects: Templating Object/Datastore mapping Repository support
  • 3. Overview - Templates The main purpose of a Spring Data template (and all other Spring templates) is resource allocation and exception translation. A template offers store specific operations like saving, updating and deleting a single record or for executing queries or map/reduce jobs. But all these methods work only for the corresponding underlying datastore. MongoDb Template Configuration Example <!-- Connection to MongoDB server --> <mongo:db-factory host="localhost" port="27017" dbname="test" /> <!-- MongoDB Template --> <bean id="mongoTemplate“ class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/> </bean>
  • 4. Overview - Object/Datastore Mapping With Spring Data, this support is extended to NoSQL datastores with object-like data structures. But these data structures can be quite different from each other, so it would be difficult to make up a common API for object/datastore mapping. Each type of datastore comes with its own set of annotations to provide the needed meta information for the mapping. JPA MongoDB Neo4j @Entity @Document( collection="usr") @NodeEntity @Table(name="TUSR") public class User {    public class User {    public class User {    @Id   private String id;    @GraphId   Long id;   @Id    private String id; @Field("fn")   private String name;     private String name;    @Column(name="fn")   private String name;    private Date lastLogin; private Date lastLogin; private Date lastLogin;  ... ... ... } } }
  • 5. Overview - Repository Support generic support for CRUD and paging , sorting by providing special parameters to the finder methods for all persistence stores The main advantages of repository support are: The developer writes a lot less boilerplate code Queries can by defined alongside the finder method and its documentation As a bonus, the JPQL queries are compiled as soon as the Spring context is assembled, not the first time you use the query, which makes it easier to detect syntax errors
  • 6. Data Model  Domain Model Customer Address <<MappedSuperClass>> AbstractEntity CREATE TABLE customer ( id BIGINT IDENTITY PRIMARY KEY, firstname VARCHAR(255), lastname VARCHAR(255), email_address VARCHAR(255)); <<Entity>> CREATE UNIQUE INDEX ix_customer_email Customer ON CUSTOMER (email_address ASC); CREATE TABLE address ( id BIGINT IDENTITY PRIMARY KEY, customer_id BIGINT CONSTRAINT address_customer_ref REFERENCES customer (id), street VARCHAR(255), city VARCHAR(255), <<Entity>> <<Embeddable>> country VARCHAR(255)); Address EmailAddress Step1. “Define Domain Model”
  • 7. AbstractEntity  Customer @M appedSupercl ass @Entity public class AbstractEntity { public class Customer extends AbstractEntity { @Id private String firstname, lastname; @GeneratedValue(strategy = GenerationT ype. AUTO) private Long id; @Col umn(unique = true) private EmailAddress emailAddress; public Long getId() { return id; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = } true) @JoinColumn(nam e = "custom er_id") public boolean equals(Object obj) { private Set<Address> addresses = new HashSet<Address>(); if (this == obj) { return true; public Customer(String firstname, String lastname) { } Assert.hasText(firstname); if (this.id == null || obj == null || ! Assert.hasText(lastname); (this.getClass().equals(obj.getClass()))) { return false; this.firstname = firstname; } this.lastname = lastname; } AbstractEntity that = (AbstractEntity) obj; protected Customer() { return this.id.equals(that.getId()); } } public int hashCode() { public void add(Address address) { return id == null ? 0 : id.hashCode(); } Assert.notNull(address); } this.addresses.add(address); } … @MappedSuperclass to express that it is not a If there were demand to customize the names of the managed columns to which the properties would be persisted, entity class on its own but rather will be extended you could use the @Column annotation. by entity classes. Step1. “Define Domain Model”
  • 8. Address  CustomerRepository @Entity public interface CustomerRepository public class Address extends AbstractEntity { ext ends CrudRepos itory<Customer, Long> { Customer findByEmailAddress(EmailAddress emailAddress); private String street, city, country; Customer findById(Long id); List<Customer> findAll(); public Address(String street, String city, String country) { } Assert.hasText(street, "Street must not be null or empty!"); Assert.hasText(city, "City must not be null or empty!"); Assert.hasText(country, "Country must not be null or empty!"); this.street = street; this.city = city; this.country = country; Step2. “Define Repository } Interface” protected Address() { -Just only interface } …  EmailAddress @Em beddabl e public class EmailAddress { @Colum n(nam e = "email_address") private String value; public EmailAddress(String emailAddress) { Assert.isTrue(isValid(emailAddress), "Invalid email address!"); this.value = emailAddress; } the EmailAddress class is an @Embeddable, which protected EmailAddress() { will cause the persistence provider to flatten out all properties of it into the table of the } … surrounding class. Step1. “Define Domain Model”
  • 9. SpringConfig @Configuration @EnableT ransactionManagement @ComponentS can @EnableJ paReposi tories public class InfrastructureConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("classpath:sql/schema.sql") .addScript("classpath:sql/test-data.sql").build(); } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setDatabase(Database.HSQL); //vendorAdapter.setGenerateDdl(true); vendorAdapter.setShowSql(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan(getClass().getPackage().getName()); factory.setDataSource(dataSource()); return factory; } @Bean public PlatformTransactionManager transactionManager() { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory().getObject()); return txManager; } } Step3. “Configure Spring Beans”
  • 10. TestCase @RunWit h(SpringJUnit4Cl assRunner.class) @Test @Cont extConfiguration(classes = { TestConfig.cl ass }) public void saveNewCustomer() { @T ransactional Customer c = new Customer(); @Di rtiesContext //c.setFirstname("Sven"); public class TestMain { c.setLastname("Svensson"); c.setEmailAddress(new EmailAddress("sven@svensson.org")); @A utowired Address a = new Address("Storgaten 6", "Trosa", "Sweden"); CustomerRepository repository; c.add(a); repository.save(c); @Autowired System.out.println(repository.findAll()); DataSource dataSource; Customer result = repository.findOne(c.getId()); assertThat(result, is(notNullValue())); @Test //assertThat(result.getFirstName(), is("Sven")); public void testFindAll() { assertThat(result.getEmailAddress().toString(), is(notNullValue())); List< Custom er> results = reposi tory.findAl l(); } assertThat(results, is(notNullValue())); assertThat(results, hasSize(3)); assertThat(results.get(0), notNullValue()); @Test(expected = DataIntegrityViolationException.class) assertThat(results.get(1), notNullValue()); public void saveNewCustomerWithDuplicateEmail() { assertThat(results.get(2), notNullValue()); Customer c = new Customer("Bob","Doe"); } c.setEmailAddress(new EmailAddress("bob@doe.com")); Address a = new Address("66 Main St", "Middletown", "USA"); @Test c.add(a); public void testFindById() { repository.save(c); Customer res ult = repository.findOne(100L); } assertThat(result, is(notNullValue())); assertThat(result.getFirstname(), is("John")); @Test } public void deleteCustomer() { Customer c = repository.findOne(100L); @Test repository.delete(c); public void testFindByEmail() { Customer result = repository.findOne(100L); assertThat(result, is(nullValue())); Customer result = repository.fi ndByEm ail Address(new EmailA ddress("bob@doe.com")); assertThat(result, is(notNullValue())); } assertThat(result.getFirstname(), is("Bob")); } } Step4. “Test it…”
  • 11. Document Model  Domain Model Customer Email (*)Address AbstractDocument { firstname : "Dave", lastname : "Matthews", email : { email : "dave@dmband.com" <<Document>> }, addresses : [ Customer { street : "Broadway", city : "New York", country : "United States" } ] } <<Entity>> <<Embeddable>> Address EmailAddress Step1. “Define Domain Model”
  • 12. AbstractDocument  Customer public class AbstractDocument { @Document public class Customer extends AbstractDocument { @Id private BigInteger id; private String firstname, lastname; public BigInteger getId() { @Fi eld("em ail ") return id; @Indexed(unique = true) } private EmailAddress emailAddress; private Set<Address> addresses = new HashSet<Address>(); public boolean equals(Object obj) { public Customer(String firstname, String lastname) { if (this == obj) { return true; Assert.hasText(firstname); } Assert.hasText(lastname); if (this.id == null || obj == null || ! this.firstname = firstname; (this.getClass().equals(obj.getClass()))) { this.lastname = lastname; return false; } } protected Customer() { AbstractDocument that = (AbstractDocument) obj; } return this.id.equals(that.getId()); … } public int hashCode() { return id == null ? 0 : id.hashCode(); } } Step1. “Define Domain Model”
  • 13. Address  CustomerRepository public class Address { public interface CustomerRepository ext ends CrudRepos itory<Customer, Long> { private final String street, city, country; Customer findByEmailAddress(EmailAddress emailAddress); Customer findById(Long id); public Address(String street, String city, String country) { List<Customer> findAll(); } Assert.hasText(street, "Street must not be null or empty!"); Assert.hasText(city, "City must not be null or empty!"); Assert.hasText(country, "Country must not be null or empty!"); this.street = street; this.city = city; this.country = country; Step2. “Define Repository … } Interface” -Just only interface  EmailAddress public class EmailAddress { @F iel d("emai l") private final String value; public EmailAddress(String emailAddress) { Assert.isTrue(isValid(emailAddress), "Invalid email address!"); this.value = emailAddress; } protected EmailAddress() { } … Step1. “Define Domain Model”
  • 14. SpringConfig @Configuration @ComponentS can @EnableM ongoRepositories(baseP ackages="com.mck ang.springdata.mongo") class ApplicationConfig extends AbstractMongoConfiguration { @Autowired private List<Converter<?, ?>> converters; protected String getDatabaseName() { return "e-store"; } public Mongo mongo() throws Exception { Mongo mongo = new Mongo("127.0.0.1"); mongo.setWriteConcern(WriteConcern.FSYNC_SAFE); return mongo; } public CustomConversions customConversions() { return new CustomConversions(converters); } protected String get MappingBasePackage () { return "com.mckang.springdata.mongo"; } } Step3. “Configure Spring Beans”
  • 15. TestCase @RunWith(S pringJUnit4ClassRunner.class ) @Test @ContextConfigurati on(cl asses = { T es tConfi g.class }) public void saveNewCustomer() { @T ransactional Customer c = new Customer(); @DirtiesContext //c.setFirstname("Sven"); public class TestMain { c.setLastname("Svensson"); c.setEmailAddress(new EmailAddress("sven@svensson.org")); @Autowi red Address a = new Address("Storgaten 6", "Trosa", "Sweden"); Custom erRepository reposi tory; c.add(a); repository.save(c); @Autowired } DataSource dataSource; @Test @Test(expected = DataIntegrityViolationException.class) public void testFindAll() { public void saveNewCustomerWithDuplicateEmail() { List<Custom er> results = repository.f indAll (); Customer c = new Customer("Bob","Doe"); assertThat(results, is(notNullValue())); c.setEmailAddress(new EmailAddress("bob@doe.com")); assertThat(results, hasSize(3)); Address a = new Address("66 Main St", "Middletown", "USA"); assertThat(results.get(0), notNullValue()); c.add(a); assertThat(results.get(1), notNullValue()); repository.save(c); assertThat(results.get(2), notNullValue()); } } @Test @Test public void deleteCustomer() { public void testFindById() { Customer c = repository.findOne(100L); Custom er result = repos it ory.findOne(100L); repository.delete(c); assertThat(result, is(notNullValue())); } assertThat(result.getFirstname(), is("John")); } } @Test public void testFindByEmail() { Customer result = repository.f indByEm ai lAddres s(new Em ail Address("bob@doe.com")); } Step4. “Test it…” (Need Fixture…)
  • 16. Graph Database Neo4j is the leading implementation of a property graph database. It is written predominantly in Java and leverages a custom storage format and the facilities of the Java Transaction Architecture (JTA) to provide XA transactions. Neo4j integrates a transactional, pluggable indexing subsystem that uses Lucene as the default. The index is used primarily to locate starting points for traversals. Its second use is to support unique entity creation.
  • 17. Cypher statement With the declarative Cypher query language, Neo4j makes it easier to get started for everyone who knows SQL from working with relational databases. enabling users to define sophisticated queries like “find me all the customers who have friends who have recently bought similar products.” Like other query languages, it supports filtering, grouping, and paging. Cypher allows easy creation, deletion, update, and graph construction.
  • 18.
  • 19. Graph Model  Domain Model AbstractEntity Customer Address <<NodeEntity>> Customer Address <<NodeEntity>> EmailAddress Address Step1. “Define Domain Model”
  • 20. AbstractDocument  Customer public abstract class AbstractEntity { @NodeEnti ty public class Customer extends AbstractEntity { @GraphId private Long id; private String firstName, lastName; public Long getId() { @Indexed(unique = true) return id; private String emailAddress; } @Rel atedT o(type = "ADDRESS") @Override private Set<Address> addresses = new HashSet<Address>(); public boolean equals(Object obj) { public Customer(String firstName, String lastName, String emailAddress) { if (this == obj) { return true; Assert.hasText(firstName); } Assert.hasText(lastName); Assert.hasText(emailAddress); if (id == null || obj == null || ! getClass().equals(obj.getClass())) { this.firstName = firstName; return false; this.lastName = lastName; } this.emailAddress = emailAddress; return id.equals(((AbstractEntity) obj).id); } } protected Customer() { @Override } public int hashCode() { … return id == null ? 0 : id.hashCode(); } } Step1. “Define Domain Model”
  • 21. Address  CustomerRepository @NodeEntity public interface CustomerRepository extends GraphRepository<Customer> { public class Address extends AbstractEntity { Customer findOne(Long id); private String street, city; <C extends Customer> C save(C customer); public Address(String street, String city) { Customer findByEmailAddress(String emailAddress); this.street = street; } this.city = city; } public Address() { } Step2. “Define Repository … Interface” -Just only interface  EmailAddress public class EmailAddress { private final String value; public EmailAddress(String emailAddress) { Assert.isTrue(isValid(emailAddress), "Invalid email address!"); this.value = emailAddress; } protected EmailAddress() { } … Step1. “Define Domain Model”
  • 22. SpringConfig @Configuration @ComponentS can @ImportResource("cl asspath:ME TA-INF /spring/spring-data-context.xml ") @EnableT ransactionManagement class ApplicationConfig { @Bean(destroyMethod = "shutdown") public GraphDatabaseService graphDatabaseService() { //return new EmbeddedGraphDatabase("target/graph.db"); return new SpringRestGraphDatabase("http://localhost:7474/db/data"); } } <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:neo4j="http://www.springframework.org/schema/data/neo4j" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd"> <!--neo4j:config storeDi rectory="target/graph.db" /--> <neo4j :c onfig graphDatabaseService= "graphDatabaseService" /> <neo4j :repositori es base-package="com. mckang.springdata.neo4j" /> </beans> Step3. “Configure Spring Beans”
  • 23. TestCase @RunWith(SpringJUni t4ClassRunner.cl ass) @Context Confi guration(classes = { TestConfig.class }) @Test public class TestMain { public void preventsDuplicateEmail() { @Autowired final EmailAddress email = new EmailAddress("dave@dmband.com"); CustomerReposi tory repository; Customer dave = repository.findByEmailAddress(email.getEmail()); Customer anotherDave = new Customer("Dave", "Matthews",dave.getEmailAddress()); @Autowired repository.save(anotherDave); DataSource dataSource; } @Test } public void savesCustomerCorrectly() { EmailAddress email = new EmailAddress("alicia@keys.com"); Customer alicia = new Customer("Alicia", "Keys",email.getEmail()); // todo alicia.add(new Address("27 Broadway", "New York")); Customer result = repository.save(alicia); assertThat(result.getId(), is(notNullValue())); } @Test public void readsCustomerByEmail() { EmailAddress email = new EmailAddress("alicia@keys.com"); Customer alicia = new Customer("Alicia", "Keys",email.getEmail()); repository.save(alicia); Customer result = repository.findByEmailAddress(email.getEmail()); assertThat(result, is(alicia)); } Step4. “Test it…” (Need Fixture…)