SpringSource and MongoDB Chris Richardson Author of POJOs in Action Founder of CloudFoundry.com Chris.Richardson@SpringSource.Com @crichardson
Presentation Goal How SpringSource is making it easier for Java and Grails developers to build MongoDB applications Slide 2
About Chris •  Grew up in England and live in Oakland, CA •  Over 25+ years of software development experience including 14 years of Java •  Speaker at JavaOne, SpringOne, NFJS, JavaPolis, Spring Experience, etc. •  Organize the Oakland JUG and the Groovy Grails meetup http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/ Slide 3
Agenda o  Introduction to Spring o  Spring Data and MongoDB o  Introduction to Grails o  Using Grails with MongoDB Slide 4
The Spring framework o  Rapid evolution n  Spring 1.0 – March 2004 n  Spring 2.0 – October 2006 n  Spring 2.5 – December 2007 n  Spring 3.0 – December 2009 n  … n  Complete backward compatibility o  De facto standard programming model for enterprise Java o  Two million+ developers Slide 5
The Spring framework ecosystem Framework Description Spring framework The foundation Spring.NET .NET port of the Spring framework Spring Security (a.k.a. Acegi) Extensible framework providing authentication, authorization and instance-level security Spring Web Flow An excellent framework for building multi-page flows Spring Web Services Contract-first, document–centric SOAP web services Spring Dynamic Modules for OSGI Deploy Spring applications on OSGI Spring Batch Powerful batch processing framework Spring Integration Implements enterprise integration patterns Spring BlazeDS integration Support for Adobe BlazeDS Spring AMQP AMQP messaging, i.e. RabbitMQ Spring Gemfire Simplify Gemfire application development … Slide 6
Spring programming model Dependency Injection: resolves inter-component Benefits: dependencies, • Improved developer metadata-driven productivity • Higher quality code • Portability across application servers POJO Aspect-Oriented Programming: Portable Service modular Abstractions: implementation of Transactions, data cross cutting access, … concerns Slide 7
Portable service abstractions o  Portable service abstractions insulate developer Business Logic from low-level programming Infrastructure code o  Less code Spring o  Simpler code Transactions Security Data access o  Increased … productivity o  Portable code Runtime Environment Slide 8
Spring JDBC example @Repository class ActorDaoImpl implements ActorDao { SimpleJdbcTemplate hides @Autowired the low-level, messy private SimpleJdbcTemplate simpleJdbcTemplate; details of using JDBC public Actor findActor(String specialty, int age) { String sql = "select id, first_name, last_name from T_ACTOR" + " where specialty = ? and age = ?"; RowMapper<Actor> mapper = new RowMapper<Actor>() { public Actor mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setId(rs.getLong("id")); actor.setFirstName(rs.getString("first_name")); actor.setLastName(rs.getString("last_name")); return actor; } }; return simpleJdbcTemplate.queryForObject(sql, mapper, specialty, age); } Slide 9
Externalized database configuration @Configuration public class AppConfig { private @Value("#{jdbcProperties.url}") String jdbcUrl; private @Value("#{jdbcProperties.username}") String username; private @Value("#{jdbcProperties.password}") String password; @Bean public SimpleJdbcTemplate jdbcTemplate() { return new SimpleJdbcTemplate (dataSource()); } @Bean public DataSource dataSource() { return new DriverManagerDataSource(jdbcUrl, username, password); } } Reads DB configuration <context:component-scan base-package="..."/> from file <util:properties id="jdbcProperties" location="…/jdbc.properties"/> Slide 10
Spring DataAccessException o Base class for exceptions thrown by DataAccess Exception DAOs o Consistent exception Concurrency Failure Exception ... handling across Hibernate, JPA, JDBC, Optimistic LockingFailure etc. Exception Pessimistic LockingFailure Exception o Unchecked exception o Extensible exception CannotSerialize mapping: CannotAcquire LockException Transaction Exception SqlExceptionTranslator 11
Agenda o  Introduction to the Spring framework o  Spring Data and MongoDB o  Introduction to Grails o  Using Grails with MongoDB Slide 12
Spring Data Project Goals o  Bring classic Spring value propositions to a wide range of NoSQL databases: n  Productivity n  Programming model consistency: E.g. <NoSQL>Template classes n  “Portability” o  Many entry points to use n  Auto-generated repository implementations n  Opinionated APIs (Think JdbcTemplate) n  Object Mapping (Java and GORM) n  Cross Store Persistence Programming model n  Productivity support in Roo and Grails Slide 13
MongoDB API usage patterns o  Create and store Mongo singleton o  Externalized server details o  Inserts/Updates n  Map application POJO è DBObject n  mongo.getDatabase(…).getCollection(…) n  Partial document updates o  Queries n  mongo.getDatabase(…).getCollection(…) n  Iterate through Cursor n  Map DBObject è application POJO Ø  Higher-level than JDBC but still repetitive, … Slide 14
Spring Data - MongoDB o  MongoTemplate o  Generic repository implementation o  Querydsl integration o  Cross-store persistence Slide 15
MongoTemplate Simplifies data MongoTemplate POJO ó DBObject access databaseName mapping Translates userId Password exceptions defaultCollectionName writeConcern writeResultChecking <<interface>> save() MongoConvertor insert() write(Object, DBObject) remove() read(Class, DBObject) updateFirst() findOne() find() … SimpleMongo uses Converter Mongo MongoMapping (Java Driver class) Converter Slide 16
Example entity public class Restaurant { private String id; private String name; private List<MenuItem> menuItems; public Restaurant() { } public class MenuItem { private String name; public Restaurant(String name) { private double price; this.name = name; … public MenuItem() { } } public String getName() { return name; } public MenuItem(String name, double price) { this.name = name; public void setName(String name) { this.price = price; this.name = name; } } …getters and setters… …getters and setters… Slide 17
Example data access code @Repository public class RestaurantRepository { @Autowired private MongoTemplate mongoTemplate; public static final String RESTAURANTS_COLLECTION = "restaurants2"; public void add(Restaurant restaurant) { mongoTemplate.save(RESTAURANTS_COLLECTION, restaurant); } public List<Restaurant> findRestaurantsByName(String restaurantName) { return mongoTemplate.find(RESTAURANTS_COLLECTION, new Query(where("name").is(restaurantName)), Restaurant.class); } Slide 18
Mongo document { "_id" : ObjectId("4d977f55d3fe3119c904e026"), "menuItems" : [ { "name" : "Tandoori Portobello Mushrooms", "price" : 5.5 }, { "name" : "Duck Curry Kerala", "price" : 15 } ], "name" : "Ajanta" } Slide 19
Spring MongoDB Example - Config @Configuration public class MongoDbExampleConfig { private @Value("#{mongoDbProperties.databaseName}") String mongoDbDatabase; private @Value("#{mongoDbProperties.host}") String mongoDbHost; @Bean public Mongo mongo() throws Exception { Singleton return new Mongo(mongoDbHost); } @Bean public MongoTemplate mongoTemplate(Mongo mongo) { return new MongoTemplate(mongo, mongoDbDatabase); }… <beans> <context:annotation-config/> External Config <context:component-scan base-package="net.chrisrichardson.mongodb.example"/> mongodb.properties: <util:properties id="mongoDbProperties" location="mongodb.properties"/> databaseName=demo1 </beans> host=192.168.253.150 Slide 20
Spring MongoDB Example Test public class MongoDbExampleTest { @Autowired private RestaurantRepository restaurantRepository; @Test public void test() { Restaurant ajanta = makeAjantaRestaurant(); restaurantRepository.add(ajanta); List<Restaurant> results = restaurantRepository.findRestaurantsByName("Ajanta"); assertRestaurantFound(ajanta, results); } private Restaurant makeAjantaRestaurant() { Restaurant ajanta = new Restaurant("Ajanta"); ajanta.add(new MenuItem("Tandoori Portobello Mushrooms", 5.50)); ajanta.add(new MenuItem("Duck Curry Kerala", 15.00)); return ajanta; } … Slide 21
Update example @Repository public class RestaurantRepository { public void addMenuItem(String restaurantId, MenuItem newMenuItem) { DBObject dbo = new BasicDBObject(); mongoTemplate.getConverter().write(newMenuItem, dbo); mongoTemplate.updateFirst(RESTAURANTS_COLLECTION, new Query(where("_id").is(new ObjectId(restaurantId))), new Update().push("menuItems", dbo)); } Atomic, in-place update of document Slide 22
Callbacks – access driver API with exception translation @Test public void testDbCallback() { Exceptions are Restaurant ajanta = makeAjantaRestaurant(); translated restaurantRepository.add(ajanta); assertCollectionExists("restaurants2"); } private Void assertCollectionExists(final String collectionName) { return mongoTemplate.execute(new DbCallback<Void>(){ @Override public Void doInDB(DB db) { Set<String> collectionNames = db.getCollectionNames(); Assert.assertTrue("Missing from " + collectionNames, collectionNames.contains(collectionName)); return null; }}); } Slide 23
Generic Mongo Repositories o  Generic Repositories support n  Basic CRUD methods n  Dynamic finders n  Pagination and sorting o  You define interface that extends Repository interface o  Spring Data generates Mongo-specific implementation at runtime Slide 24
Example Mongo Generic Repository public class Person { private ObjectId id; private String firstname; private String lastname; … getters and setters } interface PersonRepository extends MongoRepository<Person, ObjectId> { List<Person> findByLastname(String lastName); } Person p = new Person("John", "Doe"); personRepository.save(p); Person p2 = personRepository.findOne(p.getId()); List<Person> johnDoes = personRepository.findByLastname("Doe"); assertEquals(1, johnDoes.size()); Slide 25
Example Mongo Repository config <bean> <mongo:repositories base-package="net.chrisrichardson.mongodb.example.mongorepository" mongo-template-ref="mongoTemplate" /> </beans> Scans classpath looking for subtypes of MongoRepository in the base package Slide 26
Richer mapping Annotations define mapping: @Document, @Id, @Indexed, @PersistanceConstructor, @Document @CompoundIndex, @DBRef, public class Person { @GeoSpatialIndexed, @Value @Id Map fields instead of properties è private ObjectId id; no getters or setters required private String firstname; Non-default constructor @Indexed private String lastname; Index generation @PersistenceConstructor public Person(String firstname, String lastname) { this.firstname = firstname; this.lastname = lastname; } …. } Slide 27
Richer mapping configuration @Configuration public class MongoExampleConfig extends AbstractMongoConfiguration { … @Override public MongoTemplate mongoTemplate() throws Exception { return new MongoTemplate(mongo(), mongoDbDatabase, null, mappingMongoConverter()); } @Override public String getMappingBasePackage() { return Person.class.getPackage().getName(); } } Slide 28
Support for the QueryDSL project Generated from Type-safe domain model class composable queries QPerson person = QPerson.person; Predicate predicate = person.homeAddress.street1.eq("1 High Street") .and(person.firstname.eq("John")) List<Person> people = personRepository.findAll(predicate); assertEquals(1, people.size()); assertPersonEquals(p, people.get(0)); Slide 29
Cross-store/polyglot persistence Person person = new Person(…); @Entity public class Person { entityManager.persist(person); // In Database @Id private Long id; Person p2 = entityManager.find(…) private String firstname; private String lastname; // In MongoDB @RelatedDocument private Address address; { "_id" : ObjectId(”….."), "_entity_id" : NumberLong(1), "_entity_class" : "net.. Person", "_entity_field_name" : "address", "zip" : "94611", "street1" : "1 High Street", …} Slide 30
Spring MongoDB – Future Ideas o  MongoTemplate n  Support common map-reduce operations from Mongo Cookbook n  GridFS integration o  Tighter integration with Spring MVC for activity monitoring n  See current example code on github Slide 31
Agenda o  Introduction to Spring o  Spring Data and MongoDB o  Introduction to Grails o  Using Grails with MongoDB Slide 32
Grails o  Open-source web application framework o  Uses Groovy – dynamic programming language for the JVM o  Builds on mature frameworks such as Spring Slide 33
GORM = Grails Object Relational Mapping o  Uses convention over configuration n  Defaults for which classes to persist n  Defaults for their O/R mapping o  Leverages the meta-object protocol n  Adds persistence methods and properties to domain classes n  No equivalent of Hibernate Session n  Avoids the need for dependency injection n  Eliminates many DAO cookie-cutter methods Slide 34
Database access made easy customer class Customer { <<table>> String name id <<pk>> } version name Customer c = new Customer("John Doe") if (!c.save()) fail "validation failed: ${c.errors}" GORM adds Methods and Customer c2 = Customer.get(c.id) properties to class at runtime c2.delete() assertNull Customer.get(c.id) def customers = Customer.findAllByName(“Fred”) Slide 35
Relationships don’t have to be difficult customer class Customer { <<table>> String name id <<pk>> static hasMany = [ accounts : Account] version } name class Account { account static belongsTo = [customer: Customer] <<table>> double balance id <<pk>> } version customer <<fk>> Customer c = <…> balance Account a = new Account(…) c.addToAccounts(a) assertSame c, a.customer assertTrue c.accounts.contains(a) Slide 36
When the defaults aren’t right class Customer { static transients = ["networth"] static mapping = { id column: 'customer_id' crc_customer <<table>> table 'crc_customer' columns { customer_id <<pk>> version name column: 'customer_name' customer_name } } def getNetworth() { …} … } Slide 37
Agenda o  Introduction to Spring o  Spring Data and MongoDB o  Introduction to Grails o  Using Grails with MongoDB Slide 38
GORM for MongoDB o  Extends GORM to support MongoDB o  Announced Nov 2010 o  Currently 1.0M5 o  Builds on n  Spring Data for MongoDB n  Spring Data Mapping Slide 39
GORM/MongoDB example grails uninstall-plugin hibernate grails install-plugin mongodb class Customer { String name Unchanged Address address static hasMany = [ accounts : Account] static embedded = ['address'] } class Address { String street class Account { String city static belongsTo = [customer: Customer] String state double balance String zip } } DataSource.groovy mongo { host = "localhost" } Slide 40
GORM/MongoDB example > db.customer.find() { "_id" : NumberLong(24), "address" : { "city" : "Oakland", "state" : "CA", "street" : "1 High Street", "zip" : "94619" }, "name" : "John Doe" } { "_id" : NumberLong(25), "address" : { "city" : "Oakland", "state" : "CA", "street" : "101 Broadway", "zip" : "94619" }, "name" : "Mary Jane" } > db.account.find() { "_id" : NumberLong(1), "balance" : 60, "customer" : NumberLong(24), "name" : "Checking" } { "_id" : NumberLong(2), "balance" : 100, "customer" : NumberLong(24), "name" : "Savings" } { "_id" : NumberLong(3), "balance" : 0, "customer" : NumberLong(25), "name" : "Checking" } o  Domain class ó Collection o  Property ó Attribute o  Relationship ó "FK attribute" Slide 41
Cloud Foundry supports Mongo o  MongoDB is one of the provided services è Deploy your MongoDB applications in seconds Slide 42
Summary o  Polyglot persistence is here to stay o  Spring Data is here to help you o  GORM let’s you use the familiar and powerful GORM API with MongoDB o  Deploy your Mongo application on CloudFoundry.com o  More info at n  http://www.springframework.org/spring-data n  http://www.cloudfoundry.com/ Slide 43
Next steps Checkout Spring Data Consider contributing Deploy on CloudFoundry.com My contact information chris.richardson@springsource.com Twitter: @crichardson Slide 44

MongoDB for Java Developers with Spring Data

  • 1.
    SpringSource and MongoDB ChrisRichardson Author of POJOs in Action Founder of CloudFoundry.com Chris.Richardson@SpringSource.Com @crichardson
  • 2.
    Presentation Goal How SpringSource is making it easier for Java and Grails developers to build MongoDB applications Slide 2
  • 3.
    About Chris •  Grew up in England and live in Oakland, CA •  Over 25+ years of software development experience including 14 years of Java •  Speaker at JavaOne, SpringOne, NFJS, JavaPolis, Spring Experience, etc. •  Organize the Oakland JUG and the Groovy Grails meetup http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/ Slide 3
  • 4.
    Agenda o  Introduction toSpring o  Spring Data and MongoDB o  Introduction to Grails o  Using Grails with MongoDB Slide 4
  • 5.
    The Spring framework o Rapid evolution n  Spring 1.0 – March 2004 n  Spring 2.0 – October 2006 n  Spring 2.5 – December 2007 n  Spring 3.0 – December 2009 n  … n  Complete backward compatibility o  De facto standard programming model for enterprise Java o  Two million+ developers Slide 5
  • 6.
    The Spring frameworkecosystem Framework Description Spring framework The foundation Spring.NET .NET port of the Spring framework Spring Security (a.k.a. Acegi) Extensible framework providing authentication, authorization and instance-level security Spring Web Flow An excellent framework for building multi-page flows Spring Web Services Contract-first, document–centric SOAP web services Spring Dynamic Modules for OSGI Deploy Spring applications on OSGI Spring Batch Powerful batch processing framework Spring Integration Implements enterprise integration patterns Spring BlazeDS integration Support for Adobe BlazeDS Spring AMQP AMQP messaging, i.e. RabbitMQ Spring Gemfire Simplify Gemfire application development … Slide 6
  • 7.
    Spring programming model Dependency Injection: resolves inter-component Benefits: dependencies, • Improved developer metadata-driven productivity • Higher quality code • Portability across application servers POJO Aspect-Oriented Programming: Portable Service modular Abstractions: implementation of Transactions, data cross cutting access, … concerns Slide 7
  • 8.
    Portable service abstractions o Portable service abstractions insulate developer Business Logic from low-level programming Infrastructure code o  Less code Spring o  Simpler code Transactions Security Data access o  Increased … productivity o  Portable code Runtime Environment Slide 8
  • 9.
    Spring JDBC example @Repository classActorDaoImpl implements ActorDao { SimpleJdbcTemplate hides @Autowired the low-level, messy private SimpleJdbcTemplate simpleJdbcTemplate; details of using JDBC public Actor findActor(String specialty, int age) { String sql = "select id, first_name, last_name from T_ACTOR" + " where specialty = ? and age = ?"; RowMapper<Actor> mapper = new RowMapper<Actor>() { public Actor mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setId(rs.getLong("id")); actor.setFirstName(rs.getString("first_name")); actor.setLastName(rs.getString("last_name")); return actor; } }; return simpleJdbcTemplate.queryForObject(sql, mapper, specialty, age); } Slide 9
  • 10.
    Externalized database configuration @Configuration publicclass AppConfig { private @Value("#{jdbcProperties.url}") String jdbcUrl; private @Value("#{jdbcProperties.username}") String username; private @Value("#{jdbcProperties.password}") String password; @Bean public SimpleJdbcTemplate jdbcTemplate() { return new SimpleJdbcTemplate (dataSource()); } @Bean public DataSource dataSource() { return new DriverManagerDataSource(jdbcUrl, username, password); } } Reads DB configuration <context:component-scan base-package="..."/> from file <util:properties id="jdbcProperties" location="…/jdbc.properties"/> Slide 10
  • 11.
    Spring DataAccessException o Base classfor exceptions thrown by DataAccess Exception DAOs o Consistent exception Concurrency Failure Exception ... handling across Hibernate, JPA, JDBC, Optimistic LockingFailure etc. Exception Pessimistic LockingFailure Exception o Unchecked exception o Extensible exception CannotSerialize mapping: CannotAcquire LockException Transaction Exception SqlExceptionTranslator 11
  • 12.
    Agenda o  Introduction tothe Spring framework o  Spring Data and MongoDB o  Introduction to Grails o  Using Grails with MongoDB Slide 12
  • 13.
    Spring Data ProjectGoals o  Bring classic Spring value propositions to a wide range of NoSQL databases: n  Productivity n  Programming model consistency: E.g. <NoSQL>Template classes n  “Portability” o  Many entry points to use n  Auto-generated repository implementations n  Opinionated APIs (Think JdbcTemplate) n  Object Mapping (Java and GORM) n  Cross Store Persistence Programming model n  Productivity support in Roo and Grails Slide 13
  • 14.
    MongoDB API usagepatterns o  Create and store Mongo singleton o  Externalized server details o  Inserts/Updates n  Map application POJO è DBObject n  mongo.getDatabase(…).getCollection(…) n  Partial document updates o  Queries n  mongo.getDatabase(…).getCollection(…) n  Iterate through Cursor n  Map DBObject è application POJO Ø  Higher-level than JDBC but still repetitive, … Slide 14
  • 15.
    Spring Data -MongoDB o  MongoTemplate o  Generic repository implementation o  Querydsl integration o  Cross-store persistence Slide 15
  • 16.
    MongoTemplate Simplifies data MongoTemplate POJO ó DBObject access databaseName mapping Translates userId Password exceptions defaultCollectionName writeConcern writeResultChecking <<interface>> save() MongoConvertor insert() write(Object, DBObject) remove() read(Class, DBObject) updateFirst() findOne() find() … SimpleMongo uses Converter Mongo MongoMapping (Java Driver class) Converter Slide 16
  • 17.
    Example entity public classRestaurant { private String id; private String name; private List<MenuItem> menuItems; public Restaurant() { } public class MenuItem { private String name; public Restaurant(String name) { private double price; this.name = name; … public MenuItem() { } } public String getName() { return name; } public MenuItem(String name, double price) { this.name = name; public void setName(String name) { this.price = price; this.name = name; } } …getters and setters… …getters and setters… Slide 17
  • 18.
    Example data accesscode @Repository public class RestaurantRepository { @Autowired private MongoTemplate mongoTemplate; public static final String RESTAURANTS_COLLECTION = "restaurants2"; public void add(Restaurant restaurant) { mongoTemplate.save(RESTAURANTS_COLLECTION, restaurant); } public List<Restaurant> findRestaurantsByName(String restaurantName) { return mongoTemplate.find(RESTAURANTS_COLLECTION, new Query(where("name").is(restaurantName)), Restaurant.class); } Slide 18
  • 19.
    Mongo document { "_id" : ObjectId("4d977f55d3fe3119c904e026"), "menuItems" : [ { "name" : "Tandoori Portobello Mushrooms", "price" : 5.5 }, { "name" : "Duck Curry Kerala", "price" : 15 } ], "name" : "Ajanta" } Slide 19
  • 20.
    Spring MongoDB Example- Config @Configuration public class MongoDbExampleConfig { private @Value("#{mongoDbProperties.databaseName}") String mongoDbDatabase; private @Value("#{mongoDbProperties.host}") String mongoDbHost; @Bean public Mongo mongo() throws Exception { Singleton return new Mongo(mongoDbHost); } @Bean public MongoTemplate mongoTemplate(Mongo mongo) { return new MongoTemplate(mongo, mongoDbDatabase); }… <beans> <context:annotation-config/> External Config <context:component-scan base-package="net.chrisrichardson.mongodb.example"/> mongodb.properties: <util:properties id="mongoDbProperties" location="mongodb.properties"/> databaseName=demo1 </beans> host=192.168.253.150 Slide 20
  • 21.
    Spring MongoDB ExampleTest public class MongoDbExampleTest { @Autowired private RestaurantRepository restaurantRepository; @Test public void test() { Restaurant ajanta = makeAjantaRestaurant(); restaurantRepository.add(ajanta); List<Restaurant> results = restaurantRepository.findRestaurantsByName("Ajanta"); assertRestaurantFound(ajanta, results); } private Restaurant makeAjantaRestaurant() { Restaurant ajanta = new Restaurant("Ajanta"); ajanta.add(new MenuItem("Tandoori Portobello Mushrooms", 5.50)); ajanta.add(new MenuItem("Duck Curry Kerala", 15.00)); return ajanta; } … Slide 21
  • 22.
    Update example @Repository public classRestaurantRepository { public void addMenuItem(String restaurantId, MenuItem newMenuItem) { DBObject dbo = new BasicDBObject(); mongoTemplate.getConverter().write(newMenuItem, dbo); mongoTemplate.updateFirst(RESTAURANTS_COLLECTION, new Query(where("_id").is(new ObjectId(restaurantId))), new Update().push("menuItems", dbo)); } Atomic, in-place update of document Slide 22
  • 23.
    Callbacks – accessdriver API with exception translation @Test public void testDbCallback() { Exceptions are Restaurant ajanta = makeAjantaRestaurant(); translated restaurantRepository.add(ajanta); assertCollectionExists("restaurants2"); } private Void assertCollectionExists(final String collectionName) { return mongoTemplate.execute(new DbCallback<Void>(){ @Override public Void doInDB(DB db) { Set<String> collectionNames = db.getCollectionNames(); Assert.assertTrue("Missing from " + collectionNames, collectionNames.contains(collectionName)); return null; }}); } Slide 23
  • 24.
    Generic Mongo Repositories o Generic Repositories support n  Basic CRUD methods n  Dynamic finders n  Pagination and sorting o  You define interface that extends Repository interface o  Spring Data generates Mongo-specific implementation at runtime Slide 24
  • 25.
    Example Mongo GenericRepository public class Person { private ObjectId id; private String firstname; private String lastname; … getters and setters } interface PersonRepository extends MongoRepository<Person, ObjectId> { List<Person> findByLastname(String lastName); } Person p = new Person("John", "Doe"); personRepository.save(p); Person p2 = personRepository.findOne(p.getId()); List<Person> johnDoes = personRepository.findByLastname("Doe"); assertEquals(1, johnDoes.size()); Slide 25
  • 26.
    Example Mongo Repositoryconfig <bean> <mongo:repositories base-package="net.chrisrichardson.mongodb.example.mongorepository" mongo-template-ref="mongoTemplate" /> </beans> Scans classpath looking for subtypes of MongoRepository in the base package Slide 26
  • 27.
    Richer mapping Annotations define mapping: @Document, @Id, @Indexed, @PersistanceConstructor, @Document @CompoundIndex, @DBRef, public class Person { @GeoSpatialIndexed, @Value @Id Map fields instead of properties è private ObjectId id; no getters or setters required private String firstname; Non-default constructor @Indexed private String lastname; Index generation @PersistenceConstructor public Person(String firstname, String lastname) { this.firstname = firstname; this.lastname = lastname; } …. } Slide 27
  • 28.
    Richer mapping configuration @Configuration publicclass MongoExampleConfig extends AbstractMongoConfiguration { … @Override public MongoTemplate mongoTemplate() throws Exception { return new MongoTemplate(mongo(), mongoDbDatabase, null, mappingMongoConverter()); } @Override public String getMappingBasePackage() { return Person.class.getPackage().getName(); } } Slide 28
  • 29.
    Support for theQueryDSL project Generated from Type-safe domain model class composable queries QPerson person = QPerson.person; Predicate predicate = person.homeAddress.street1.eq("1 High Street") .and(person.firstname.eq("John")) List<Person> people = personRepository.findAll(predicate); assertEquals(1, people.size()); assertPersonEquals(p, people.get(0)); Slide 29
  • 30.
    Cross-store/polyglot persistence Person person = new Person(…); @Entity public class Person { entityManager.persist(person); // In Database @Id private Long id; Person p2 = entityManager.find(…) private String firstname; private String lastname; // In MongoDB @RelatedDocument private Address address; { "_id" : ObjectId(”….."), "_entity_id" : NumberLong(1), "_entity_class" : "net.. Person", "_entity_field_name" : "address", "zip" : "94611", "street1" : "1 High Street", …} Slide 30
  • 31.
    Spring MongoDB –Future Ideas o  MongoTemplate n  Support common map-reduce operations from Mongo Cookbook n  GridFS integration o  Tighter integration with Spring MVC for activity monitoring n  See current example code on github Slide 31
  • 32.
    Agenda o  Introduction toSpring o  Spring Data and MongoDB o  Introduction to Grails o  Using Grails with MongoDB Slide 32
  • 33.
    Grails o  Open-source webapplication framework o  Uses Groovy – dynamic programming language for the JVM o  Builds on mature frameworks such as Spring Slide 33
  • 34.
    GORM = GrailsObject Relational Mapping o  Uses convention over configuration n  Defaults for which classes to persist n  Defaults for their O/R mapping o  Leverages the meta-object protocol n  Adds persistence methods and properties to domain classes n  No equivalent of Hibernate Session n  Avoids the need for dependency injection n  Eliminates many DAO cookie-cutter methods Slide 34
  • 35.
    Database access madeeasy customer class Customer { <<table>> String name id <<pk>> } version name Customer c = new Customer("John Doe") if (!c.save()) fail "validation failed: ${c.errors}" GORM adds Methods and Customer c2 = Customer.get(c.id) properties to class at runtime c2.delete() assertNull Customer.get(c.id) def customers = Customer.findAllByName(“Fred”) Slide 35
  • 36.
    Relationships don’t haveto be difficult customer class Customer { <<table>> String name id <<pk>> static hasMany = [ accounts : Account] version } name class Account { account static belongsTo = [customer: Customer] <<table>> double balance id <<pk>> } version customer <<fk>> Customer c = <…> balance Account a = new Account(…) c.addToAccounts(a) assertSame c, a.customer assertTrue c.accounts.contains(a) Slide 36
  • 37.
    When the defaultsaren’t right class Customer { static transients = ["networth"] static mapping = { id column: 'customer_id' crc_customer <<table>> table 'crc_customer' columns { customer_id <<pk>> version name column: 'customer_name' customer_name } } def getNetworth() { …} … } Slide 37
  • 38.
    Agenda o  Introduction toSpring o  Spring Data and MongoDB o  Introduction to Grails o  Using Grails with MongoDB Slide 38
  • 39.
    GORM for MongoDB o Extends GORM to support MongoDB o  Announced Nov 2010 o  Currently 1.0M5 o  Builds on n  Spring Data for MongoDB n  Spring Data Mapping Slide 39
  • 40.
    GORM/MongoDB example grails uninstall-pluginhibernate grails install-plugin mongodb class Customer { String name Unchanged Address address static hasMany = [ accounts : Account] static embedded = ['address'] } class Address { String street class Account { String city static belongsTo = [customer: Customer] String state double balance String zip } } DataSource.groovy mongo { host = "localhost" } Slide 40
  • 41.
    GORM/MongoDB example > db.customer.find() {"_id" : NumberLong(24), "address" : { "city" : "Oakland", "state" : "CA", "street" : "1 High Street", "zip" : "94619" }, "name" : "John Doe" } { "_id" : NumberLong(25), "address" : { "city" : "Oakland", "state" : "CA", "street" : "101 Broadway", "zip" : "94619" }, "name" : "Mary Jane" } > db.account.find() { "_id" : NumberLong(1), "balance" : 60, "customer" : NumberLong(24), "name" : "Checking" } { "_id" : NumberLong(2), "balance" : 100, "customer" : NumberLong(24), "name" : "Savings" } { "_id" : NumberLong(3), "balance" : 0, "customer" : NumberLong(25), "name" : "Checking" } o  Domain class ó Collection o  Property ó Attribute o  Relationship ó "FK attribute" Slide 41
  • 42.
    Cloud Foundry supportsMongo o  MongoDB is one of the provided services è Deploy your MongoDB applications in seconds Slide 42
  • 43.
    Summary o  Polyglot persistenceis here to stay o  Spring Data is here to help you o  GORM let’s you use the familiar and powerful GORM API with MongoDB o  Deploy your Mongo application on CloudFoundry.com o  More info at n  http://www.springframework.org/spring-data n  http://www.cloudfoundry.com/ Slide 43
  • 44.
    Next steps Checkout Spring Data Consider contributing Deploy on CloudFoundry.com My contact information chris.richardson@springsource.com Twitter: @crichardson Slide 44