SlideShare a Scribd company logo
1 of 60
Morphia
Simplifying Persistence for Java and MongoDB
Jeff Yemin
Outline
• MongoDB
• MongoDB on the JVM
• Morphia by Example
– Model
– Test
– Output
MongoDB
• Document-oriented storage
– JSON-style documents
• Rich, document-based queries
• Full index support
• Fast in-place updates
• Convenient Javascript shell
• Customer drivers for all major language
MongoDB on the JVM
• MongoDB Java Driver
– Map-based API
• JVM language integrations
– Casbah (Scala)
– Jmongo (Ruby)
– Monger (Clojure)
• ODM (Object Document Mapper)
– Morphia
– Spring Data MongoDB
Morphia
• Object Document Mapper
– Specifed with annotations
– Implemented with reflection
• Fluent query and update APIs
– Runtime validation
Dependencies
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.google.code.morphia</groupId>
<artifactId>morphia</artifactId>
<version>0.99</version>
</dependency>
Repository
<repository>
<id>morphia</id>
<name>Morphia</name>
<url>http://morphia.googlecode.com/svn/mavenrepo/</url>
<layout>default</layout>
</repository>
Create the Datastore
Morphia morphia = new Morphia();
Mongo mongo = new Mongo();
Datastore ds = morphia.createDatastore(mongo, "test");
Let's model github
First Entity (model)
class Programmer {
String name;
}
First Entity (test)
Programmer programmer = new Programmer();
programmer.name= "Scott Hernandez";
ds.save(programmer);
First Entity (shell)
> db.Programmer.findOne()
{
"_id" : ObjectId("503292d51aa814c051554696"),
"className" : "demo.Programmer",
"name" : "Scott Hernandez"
}
@Id (model)
class Programmer {
@Id ObjectId id;
String name;
public void toString() {…}
}
@Id (test)
Programmer programmer = new Programmer();
programmer.name= "Scott Hernandez";
ds.save(programmer);
System.out.println(programmer)
@Id (toString)
Programmer{id=5032935f1aa8a8aa3485b441,
name='Scott Hernandez'}
String Id (model)
class Programmer {
@Id String githubUserName;
String name;
}
String Id (test)
Programmer programmer = new Programmer();
programmer.githubUserName = "scotthernandez";
programmer.name= "Scott Hernandez";
ds.save(programmer);
String Id (shell)
> db.Programmer.findOne()
{
"_id" : "scotthernandez",
"className" : "demo.Programmer",
"name" : "Scott Hernandez"
}
@Entity (model)
@Entity("programmers")
class Programmer {
@Id String githubUserName;
String name;
}
@Entity (shell)
> db.programmers.findOne()
{
"_id" : "scotthernandez",
"className" : "demo.Programmer",
"name" : "Scott Hernandez"
}
More primitives (model)
@Entity("programmers")
class Programmer {
@Id String githubUserName;
String name;
Date memberSince;
boolean active;
int followers;
}
More primitives (test)
Programmer scott = new Programmer();
scott.userName = "scotthernandez";
scott.name = "Scott Hernandez";
scott.since = dateFmt.parse("Aug 12, 2009");
scott.active = true;
scott.followers = 8;
ds.save(scott);
More primitives (shell)
> db.programmers.findOne()
{
"_id" : "scotthernandez",
"className" : "demo.Programmer",
"name" : "Scott Hernandez",
"memberSince" : ISODate("2009-08-12T04:00:00Z"),
"active" : true,
"followers" : 8
}
Primitive Array (Model)
@Entity("programmers")
class Programmer {
@Id String githubUserName;
String name;
Date memberSince;
boolean active;
int followers;
List<String> following;
}
Primitive Array (test)
Programmer scott = new Programmer();
scott.userName = "scotthernandez";
scott.name = "Scott Hernandez";
scott.since = dateFmt.parse("Aug 12, 2009");
scott.active = true;
scott.followers = 8;
scott.following = Arrays.asList("moraes", "stickfigure");
ds.save(scott);
Primitive Array (shell)
db.programmers.findOne()
{
"_id" : "scotthernandez",
"className" : "demo.Programmer",
"name" : "Scott Hernandez",
"memberSince" : ISODate("2009-08-12T04:00:00Z"),
"active" : true,
"followers" : 8,
"following" : [
"moraes",
"stickfigure"
]
}
@Embedded (model)
@Entity("programmers")
class Programmer {
@Id String githubUserName;
Name name;
Date memberSince;
boolean active;
int followers;
List<String> following;
}
@Embedded
class Name {
String first, last;
}
@Embedded (test)
Programmer programmer = new Programmer();
programmer.githubUserName = "scotthernandez";
programmer.name = new Name("Scott", "Hernandez");
programmer.memberSince = dateFmt.parse("Aug 12, 2009");
programmer.active = true;
programmer.followers = 8;
programmer.following = Arrays.asList("moraes", "stickfigure");
ds.save(programmer);
@Embedded (shell)
> db.programmers.findOne()
{
"_id" : "scotthernandez",
"className" : "demo.Programmer",
"name" : {
"first" : "Scott",
"last" : "Hernandez"
},
"memberSince" : ISODate("2009-08-12T04:00:00Z"),
"active" : true,
"followers" : 8,
"following" : [
"moraes",
"stickfigure"
]
}
@Embedded List (model)
@Entity("programmers")
class Programmer {
@Id String githubUserName;
Name name;
Date memberSince;
boolean active;
int followers;
List<String> following;
List<Repository> repositories;
}
@Embedded
class Name {
String first, last;
}
@Embedded
class Repository {
String name;
String forkedFrom;
}
@Embedded (test)
Programmer programmer = new Programmer();
programmer.githubUserName = "scotthernandez";
programmer.name = new Name("Scott", "Hernandez");
programmer.memberSince = dateFmt.parse("Aug 12, 2009");
programmer.active = true;
programmer.followers = 8;
programmer.following = Arrays.asList("moraes", "stickfigure");
programmer.repositories = Arrays.asList(
new Repository("docs", "mongodb/docs"),
new Repository("mongo-java-driver", "mongodb/mongo-java-driver"));
ds.save(programmer);
@Embedded List (shell)
> db.programmers.findOne()
{
"_id" : "scotthernandez",
"className" : "demo.Programmer",
…
"repositories" : [
{
"name" : "docs",
"forkedFrom" : "mongodb/docs"
},
{
"name" : "mongo-java-driver",
"forkedFrom" : "mongodb/mongo-java-driver"
}
]
}
@Reference (model)
@Entity("repos")
class Repository {
@Id ObjectId id;
@Reference Programmer owner;
String name;
String forkedFrom;
}
@Reference (test)
Programmer programmer = new Programmer();
programmer.githubUserName = "scotthernandez";
programmer.name = new Name("Scott", "Hernandez");
programmer.memberSince = dateFmt.parse("Aug 12, 2009");
programmer.active = true;
programmer.followers = 8;
programmer.following = Arrays.asList("moraes", "stickfigure");
ds.save(programmer);
Repository repo = new Repository(programmer, "docs",
"mongodb/docs");
ds.save(repo);
@Reference (shell)
> db.repos.findOne()
{
"_id" : ObjectId("503297e31aa8255abe542aaa"),
"className" : "demo.Repository",
"owner" : DBRef("programmers", "scotthernandez"),
"name" : "docs",
"forkedFrom" : "mongodb/docs"
}
Small schema change (model)
abstract class Member {
@Id String userName;
@Property("memberSince") Date since;
boolean active;
String name;
}
@Entity("programmers")
class Programmer extends Member {
int followers;
List<String> following;
}
@Entity("orgs")
class Organization extends Member {
}
@Entity("repos")
class Repository {
@Id ObjectId id;
@Reference Member owner;
String name;
@Reference(lazy=true) Repository forkedFrom;
}
Small schema change (test)
Programmer scott = new Programmer();
//…
ds.save(scott);
// save mongodb Organization
Organization mongodb = new Organization("mongodb",
"mongodb", sdf.parse("Jan 8, 2009"));
ds.save(mongodb);
// save mongodb's docs Repository
Repository mongoDocs = new Repository(mongodb, "docs");
ds.save(mongoDocs);
// save Scott's forked docs Repository
Repository scottDocs = new Repository(scott, "docs",
mongoDocs);
ds.save(scottDocs);
Small schema change (shell)
> db.orgs.findOne()
{
"_id" : "mongodb",
"className" : "demo.Organization",
"memberSince" : ISODate("2009-01-08T05:00:00Z"),
"active" : false,
"name" : "mongodb"
}
> db.programmers.findOne()
{
"_id" : "scotthernandez",
"className" : "demo.Programmer",
"memberSince" : ISODate("2009-08-12T04:00:00Z"),
"active" : true,
"name" : "Scott Hernandez"
…
}
Small schema change (shell, 2)
> db.repos.find().toArray()
[
{
"_id" : ObjectId("503298be1aa8b1d255e5d45b"),
"className" : "demo.Repository",
"owner" : DBRef("orgs", "mongodb"),
"name" : "docs"
},
{
"_id" : ObjectId("503298be1aa8b1d255e5d45c"),
"className" : "demo.Repository",
"owner" : DBRef("programmers", "scotthernandez"),
"name" : "docs",
"forkedFrom" : DBRef("repos", ObjectId("503298be1aa8b1d255e5d45b"))
}
]
Find by Equality (test)
• ds.get(Programmer.class, "scotthernandez")
• ds.find(Programmer.class, "userName", "scotthernandez")
• ds.find(Programmer.class).field("userName").equal("scotthernandez")
Find by Equality (logs)
• test.programmers query: { _id: "scotthernandez" }
• test.programmers query: { _id: "scotthernandez" }
• test.programmers query: { _id: "scotthernandez" }
Find by Range (test)
• ds.find(Programmer.class).field("followers").greaterThan(0)
• ds.find(Programmer.class).filter("followers >", 0)
• ds.find(Programmer.class).field("since"). lessThan(sdf.parse("Jan 1, 2010"))
Find by Range (logs)
• test.programmers query: { followers: { $gt: 0 } }
• test.programmers query: { followers: { $gt: 0 } }
• test.programmers query: { memberSince: { $lt: new Date(1262322000000) } }
Combining conditions (test)
ds.find(Programmer.class).
field("since").lessThan(dateFmt.parse("Jan 1, 2010")).
field("followers").greaterThan(0)
Combining conditions (logs)
test.programmers query: {
memberSince: { $lt: new Date(1262322000000) },
followers: { $gt: 0 }
}
Find by Reference (test)
ds.find(Repository.class).field("owner").equal(scott)
Find by Reference (logs)
test.repos query: {
owner: { $ref: "programmers", $id: "scotthernandez" }
}
@Indexed
• Annotation for fields
– value (IndexDirection)
– name (String)
– unique (boolean)
– dropDups (boolean)
– background (boolean)
– sparse (boolean)
• Examples
– @Indexed(value=IndexDirection.ASC, name="followers") int followers;
– @Indexed @Reference(lazy = true) Repository forkedFrom;
@Indexes and @Index
• @Indexes: Annotation for types
– value (Index[])
• @Index
– value (String)
– Others same as @Indexed
• Examples
– @Indexes(@Index("since, -followers")) public class Programmer {…}
Updating with save (test)
Programmer jeff = createJeff();
ds.save(jeff);
// jeff is following scott, so increment
// scott's followers and re-save
Programmer scott = ds.get(Programmer.class,
"scotthernandez")
scott.followers++;
ds.save(scott);
Updating with save (logs)
update test.programmers
query: {
_id: "scotthernandez",
}
update: {
_id: "scotthernandez",
className: "demo.Programmer",
followers: 9,
following: [ "moraes", "stickfigure" ],
memberSince: new Date(1250049600000),
active: true,
name: "Scott Hernandez",
}
Updating with save (shell)
> db.programmers.findOne()
{
"_id" : "scotthernandez",
"className" : "demo.Programmer",
"followers" : 9,
"following" : [
"moraes",
"stickfigure"
],
"memberSince" : ISODate("2009-08-12T04:00:00Z"),
"active" : true,
"name" : "Scott Hernandez"
}
Optimistic Concurrency (model)
@Entity
public abstract class Member {
@Id String userName;
@Property("memberSince") Date since;
boolean active;
String name;
@Version Long version;
}
Optimistic Concurrency (logs)
update test.programmers
query: {
_id: "scotthernandez",
version: 1345497713173
}
update: {
_id: "scotthernandez",
className: "demo.Programmer",
followers: 9,
following: [ "moraes", "stickfigure" ],
memberSince: new Date(1250049600000),
active: true,
name: "Scott Hernandez",
version: 1345497718181
}
Optimistic Concurrency (shell)
> db.programmers.findOne()
{
"_id" : "scotthernandez",
"className" : "demo.Programmer",
"followers" : 9,
"following" : [
"moraes",
"stickfigure"
],
"memberSince" : ISODate("2009-08-12T04:00:00Z"),
"active" : true,
"name" : "Scott Hernandez",
"version" : NumberLong("1345497660444")
}
UpdateOperations (test)
Programmer jeff = createJeff();
ds.save(jeff);
// increment followers of scott by one
UpdateOperations<Programmer> incrementFollowing =
ds.createUpdateOperations(Programmer.class).
inc("followers", 1);
Query<Programmer> queryForScott =
ds.find(Programmer.class, "userName", "scotthernandez");
ds.update(queryForScott, incrementFollowing);
Web Resources
• Morphia home: http://code.google.com/p/morphia/
• Morphia user group:
https://groups.google.com/forum/?fromgroups#!forum/morphia
• Demo code: https://github.com/jyemin/morphia-demo
– Separate commit and tag for each slide, so you
can play along
Boston Resources
• MongoDB User Group: http://www.meetup.com/Boston-
MongoDB-User-Group/
• 10gen office hours: Monthly at Dog Patch (with yours truly)
MongoDB Boston
• October 23-24
– Oct 23: Workshops on Schema Design and Operations
– Oct 24: Conference talks
– Discount code: MUG10 for 10% off tickets
– Early bird prices end Sept. 24
– Submit a talk proposal at 10gen.com/talk-proposal
– URL: 10gen.com/events/mongodb-boston
Thanks!
• Jeff Yemin
– https://twitter.com/@jeffyemin
– jeff.yemin@10gen.com
– https://github.com/jyemin/

More Related Content

What's hot

Morphia, Spring Data & Co.
Morphia, Spring Data & Co.Morphia, Spring Data & Co.
Morphia, Spring Data & Co.Tobias Trelle
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know Norberto Leite
 
Webinar: Simplifying Persistence for Java and MongoDB
Webinar: Simplifying Persistence for Java and MongoDBWebinar: Simplifying Persistence for Java and MongoDB
Webinar: Simplifying Persistence for Java and MongoDBMongoDB
 
Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Hermann Hueck
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance TuningPuneet Behl
 
NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryAlexandre Morgaut
 
Mythbusting: Understanding How We Measure the Performance of MongoDB
Mythbusting: Understanding How We Measure the Performance of MongoDBMythbusting: Understanding How We Measure the Performance of MongoDB
Mythbusting: Understanding How We Measure the Performance of MongoDBMongoDB
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
MongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() OutputMongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() OutputMongoDB
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBUwe Printz
 
Elastic Search Training#1 (brief tutorial)-ESCC#1
Elastic Search Training#1 (brief tutorial)-ESCC#1Elastic Search Training#1 (brief tutorial)-ESCC#1
Elastic Search Training#1 (brief tutorial)-ESCC#1medcl
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETTomas Jansson
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?Trisha Gee
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance TuningMongoDB
 
Getting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJSGetting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJSMongoDB
 

What's hot (19)

Morphia, Spring Data & Co.
Morphia, Spring Data & Co.Morphia, Spring Data & Co.
Morphia, Spring Data & Co.
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
 
Webinar: Simplifying Persistence for Java and MongoDB
Webinar: Simplifying Persistence for Java and MongoDBWebinar: Simplifying Persistence for Java and MongoDB
Webinar: Simplifying Persistence for Java and MongoDB
 
Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
 
greenDAO
greenDAOgreenDAO
greenDAO
 
NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love Story
 
Mythbusting: Understanding How We Measure the Performance of MongoDB
Mythbusting: Understanding How We Measure the Performance of MongoDBMythbusting: Understanding How We Measure the Performance of MongoDB
Mythbusting: Understanding How We Measure the Performance of MongoDB
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
MongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() OutputMongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() Output
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDB
 
Groovy.pptx
Groovy.pptxGroovy.pptx
Groovy.pptx
 
Elastic Search Training#1 (brief tutorial)-ESCC#1
Elastic Search Training#1 (brief tutorial)-ESCC#1Elastic Search Training#1 (brief tutorial)-ESCC#1
Elastic Search Training#1 (brief tutorial)-ESCC#1
 
Green dao
Green daoGreen dao
Green dao
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
 
The emerging world of mongo db csp
The emerging world of mongo db   cspThe emerging world of mongo db   csp
The emerging world of mongo db csp
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
 
Getting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJSGetting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJS
 

Similar to Morphia: Simplifying Persistence for Java and MongoDB

最近 node.js 來勢洶洶, 怎麼辦? 別怕, 我們也有秘密武器 RingoJS!
最近 node.js 來勢洶洶, 怎麼辦? 別怕, 我們也有秘密武器 RingoJS!最近 node.js 來勢洶洶, 怎麼辦? 別怕, 我們也有秘密武器 RingoJS!
最近 node.js 來勢洶洶, 怎麼辦? 別怕, 我們也有秘密武器 RingoJS!Liwei Chou
 
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018Codemotion
 
Spring Data MongoDB 介紹
Spring Data MongoDB 介紹Spring Data MongoDB 介紹
Spring Data MongoDB 介紹Kuo-Chun Su
 
How to use MongoDB with CakePHP
How to use MongoDB with CakePHPHow to use MongoDB with CakePHP
How to use MongoDB with CakePHPichikaway
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Murat Yener
 
Mongoose and MongoDB 101
Mongoose and MongoDB 101Mongoose and MongoDB 101
Mongoose and MongoDB 101Will Button
 
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)Red Hat Developers
 
Back to Basics 2017: Mí primera aplicación MongoDB
Back to Basics 2017: Mí primera aplicación MongoDBBack to Basics 2017: Mí primera aplicación MongoDB
Back to Basics 2017: Mí primera aplicación MongoDBMongoDB
 
This upload requires better support for ODP format
This upload requires better support for ODP formatThis upload requires better support for ODP format
This upload requires better support for ODP formatForest Mars
 
Java script at backend nodejs
Java script at backend   nodejsJava script at backend   nodejs
Java script at backend nodejsAmit Thakkar
 
NodeJs
NodeJsNodeJs
NodeJsdizabl
 
MongoDB Days Silicon Valley: Building Applications with the MEAN Stack
MongoDB Days Silicon Valley: Building Applications with the MEAN StackMongoDB Days Silicon Valley: Building Applications with the MEAN Stack
MongoDB Days Silicon Valley: Building Applications with the MEAN StackMongoDB
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Introducing the Seneca MVP framework for Node.js
Introducing the Seneca MVP framework for Node.jsIntroducing the Seneca MVP framework for Node.js
Introducing the Seneca MVP framework for Node.jsRichard Rodger
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Matthew Groves
 
Full Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLFull Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLAll Things Open
 

Similar to Morphia: Simplifying Persistence for Java and MongoDB (20)

最近 node.js 來勢洶洶, 怎麼辦? 別怕, 我們也有秘密武器 RingoJS!
最近 node.js 來勢洶洶, 怎麼辦? 別怕, 我們也有秘密武器 RingoJS!最近 node.js 來勢洶洶, 怎麼辦? 別怕, 我們也有秘密武器 RingoJS!
最近 node.js 來勢洶洶, 怎麼辦? 別怕, 我們也有秘密武器 RingoJS!
 
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
 
Spring Data MongoDB 介紹
Spring Data MongoDB 介紹Spring Data MongoDB 介紹
Spring Data MongoDB 介紹
 
How to use MongoDB with CakePHP
How to use MongoDB with CakePHPHow to use MongoDB with CakePHP
How to use MongoDB with CakePHP
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15
 
Mongoose and MongoDB 101
Mongoose and MongoDB 101Mongoose and MongoDB 101
Mongoose and MongoDB 101
 
Mongo-Drupal
Mongo-DrupalMongo-Drupal
Mongo-Drupal
 
Mongodb
MongodbMongodb
Mongodb
 
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
 
Back to Basics 2017: Mí primera aplicación MongoDB
Back to Basics 2017: Mí primera aplicación MongoDBBack to Basics 2017: Mí primera aplicación MongoDB
Back to Basics 2017: Mí primera aplicación MongoDB
 
This upload requires better support for ODP format
This upload requires better support for ODP formatThis upload requires better support for ODP format
This upload requires better support for ODP format
 
Java script at backend nodejs
Java script at backend   nodejsJava script at backend   nodejs
Java script at backend nodejs
 
NodeJs
NodeJsNodeJs
NodeJs
 
MongoDB Days Silicon Valley: Building Applications with the MEAN Stack
MongoDB Days Silicon Valley: Building Applications with the MEAN StackMongoDB Days Silicon Valley: Building Applications with the MEAN Stack
MongoDB Days Silicon Valley: Building Applications with the MEAN Stack
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Introducing the Seneca MVP framework for Node.js
Introducing the Seneca MVP framework for Node.jsIntroducing the Seneca MVP framework for Node.js
Introducing the Seneca MVP framework for Node.js
 
20120816 nodejsdublin
20120816 nodejsdublin20120816 nodejsdublin
20120816 nodejsdublin
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017
 
Full Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLFull Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQL
 
Java 7: Quo vadis?
Java 7: Quo vadis?Java 7: Quo vadis?
Java 7: Quo vadis?
 

Recently uploaded

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
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 

Recently uploaded (20)

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
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 

Morphia: Simplifying Persistence for Java and MongoDB

  • 1. Morphia Simplifying Persistence for Java and MongoDB Jeff Yemin
  • 2. Outline • MongoDB • MongoDB on the JVM • Morphia by Example – Model – Test – Output
  • 3. MongoDB • Document-oriented storage – JSON-style documents • Rich, document-based queries • Full index support • Fast in-place updates • Convenient Javascript shell • Customer drivers for all major language
  • 4. MongoDB on the JVM • MongoDB Java Driver – Map-based API • JVM language integrations – Casbah (Scala) – Jmongo (Ruby) – Monger (Clojure) • ODM (Object Document Mapper) – Morphia – Spring Data MongoDB
  • 5. Morphia • Object Document Mapper – Specifed with annotations – Implemented with reflection • Fluent query and update APIs – Runtime validation
  • 8. Create the Datastore Morphia morphia = new Morphia(); Mongo mongo = new Mongo(); Datastore ds = morphia.createDatastore(mongo, "test");
  • 10. First Entity (model) class Programmer { String name; }
  • 11. First Entity (test) Programmer programmer = new Programmer(); programmer.name= "Scott Hernandez"; ds.save(programmer);
  • 12. First Entity (shell) > db.Programmer.findOne() { "_id" : ObjectId("503292d51aa814c051554696"), "className" : "demo.Programmer", "name" : "Scott Hernandez" }
  • 13. @Id (model) class Programmer { @Id ObjectId id; String name; public void toString() {…} }
  • 14. @Id (test) Programmer programmer = new Programmer(); programmer.name= "Scott Hernandez"; ds.save(programmer); System.out.println(programmer)
  • 16. String Id (model) class Programmer { @Id String githubUserName; String name; }
  • 17. String Id (test) Programmer programmer = new Programmer(); programmer.githubUserName = "scotthernandez"; programmer.name= "Scott Hernandez"; ds.save(programmer);
  • 18. String Id (shell) > db.Programmer.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : "Scott Hernandez" }
  • 19. @Entity (model) @Entity("programmers") class Programmer { @Id String githubUserName; String name; }
  • 20. @Entity (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : "Scott Hernandez" }
  • 21. More primitives (model) @Entity("programmers") class Programmer { @Id String githubUserName; String name; Date memberSince; boolean active; int followers; }
  • 22. More primitives (test) Programmer scott = new Programmer(); scott.userName = "scotthernandez"; scott.name = "Scott Hernandez"; scott.since = dateFmt.parse("Aug 12, 2009"); scott.active = true; scott.followers = 8; ds.save(scott);
  • 23. More primitives (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : "Scott Hernandez", "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "followers" : 8 }
  • 24. Primitive Array (Model) @Entity("programmers") class Programmer { @Id String githubUserName; String name; Date memberSince; boolean active; int followers; List<String> following; }
  • 25. Primitive Array (test) Programmer scott = new Programmer(); scott.userName = "scotthernandez"; scott.name = "Scott Hernandez"; scott.since = dateFmt.parse("Aug 12, 2009"); scott.active = true; scott.followers = 8; scott.following = Arrays.asList("moraes", "stickfigure"); ds.save(scott);
  • 26. Primitive Array (shell) db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : "Scott Hernandez", "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "followers" : 8, "following" : [ "moraes", "stickfigure" ] }
  • 27. @Embedded (model) @Entity("programmers") class Programmer { @Id String githubUserName; Name name; Date memberSince; boolean active; int followers; List<String> following; } @Embedded class Name { String first, last; }
  • 28. @Embedded (test) Programmer programmer = new Programmer(); programmer.githubUserName = "scotthernandez"; programmer.name = new Name("Scott", "Hernandez"); programmer.memberSince = dateFmt.parse("Aug 12, 2009"); programmer.active = true; programmer.followers = 8; programmer.following = Arrays.asList("moraes", "stickfigure"); ds.save(programmer);
  • 29. @Embedded (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : { "first" : "Scott", "last" : "Hernandez" }, "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "followers" : 8, "following" : [ "moraes", "stickfigure" ] }
  • 30. @Embedded List (model) @Entity("programmers") class Programmer { @Id String githubUserName; Name name; Date memberSince; boolean active; int followers; List<String> following; List<Repository> repositories; } @Embedded class Name { String first, last; } @Embedded class Repository { String name; String forkedFrom; }
  • 31. @Embedded (test) Programmer programmer = new Programmer(); programmer.githubUserName = "scotthernandez"; programmer.name = new Name("Scott", "Hernandez"); programmer.memberSince = dateFmt.parse("Aug 12, 2009"); programmer.active = true; programmer.followers = 8; programmer.following = Arrays.asList("moraes", "stickfigure"); programmer.repositories = Arrays.asList( new Repository("docs", "mongodb/docs"), new Repository("mongo-java-driver", "mongodb/mongo-java-driver")); ds.save(programmer);
  • 32. @Embedded List (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", … "repositories" : [ { "name" : "docs", "forkedFrom" : "mongodb/docs" }, { "name" : "mongo-java-driver", "forkedFrom" : "mongodb/mongo-java-driver" } ] }
  • 33. @Reference (model) @Entity("repos") class Repository { @Id ObjectId id; @Reference Programmer owner; String name; String forkedFrom; }
  • 34. @Reference (test) Programmer programmer = new Programmer(); programmer.githubUserName = "scotthernandez"; programmer.name = new Name("Scott", "Hernandez"); programmer.memberSince = dateFmt.parse("Aug 12, 2009"); programmer.active = true; programmer.followers = 8; programmer.following = Arrays.asList("moraes", "stickfigure"); ds.save(programmer); Repository repo = new Repository(programmer, "docs", "mongodb/docs"); ds.save(repo);
  • 35. @Reference (shell) > db.repos.findOne() { "_id" : ObjectId("503297e31aa8255abe542aaa"), "className" : "demo.Repository", "owner" : DBRef("programmers", "scotthernandez"), "name" : "docs", "forkedFrom" : "mongodb/docs" }
  • 36. Small schema change (model) abstract class Member { @Id String userName; @Property("memberSince") Date since; boolean active; String name; } @Entity("programmers") class Programmer extends Member { int followers; List<String> following; } @Entity("orgs") class Organization extends Member { } @Entity("repos") class Repository { @Id ObjectId id; @Reference Member owner; String name; @Reference(lazy=true) Repository forkedFrom; }
  • 37. Small schema change (test) Programmer scott = new Programmer(); //… ds.save(scott); // save mongodb Organization Organization mongodb = new Organization("mongodb", "mongodb", sdf.parse("Jan 8, 2009")); ds.save(mongodb); // save mongodb's docs Repository Repository mongoDocs = new Repository(mongodb, "docs"); ds.save(mongoDocs); // save Scott's forked docs Repository Repository scottDocs = new Repository(scott, "docs", mongoDocs); ds.save(scottDocs);
  • 38. Small schema change (shell) > db.orgs.findOne() { "_id" : "mongodb", "className" : "demo.Organization", "memberSince" : ISODate("2009-01-08T05:00:00Z"), "active" : false, "name" : "mongodb" } > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "name" : "Scott Hernandez" … }
  • 39. Small schema change (shell, 2) > db.repos.find().toArray() [ { "_id" : ObjectId("503298be1aa8b1d255e5d45b"), "className" : "demo.Repository", "owner" : DBRef("orgs", "mongodb"), "name" : "docs" }, { "_id" : ObjectId("503298be1aa8b1d255e5d45c"), "className" : "demo.Repository", "owner" : DBRef("programmers", "scotthernandez"), "name" : "docs", "forkedFrom" : DBRef("repos", ObjectId("503298be1aa8b1d255e5d45b")) } ]
  • 40. Find by Equality (test) • ds.get(Programmer.class, "scotthernandez") • ds.find(Programmer.class, "userName", "scotthernandez") • ds.find(Programmer.class).field("userName").equal("scotthernandez")
  • 41. Find by Equality (logs) • test.programmers query: { _id: "scotthernandez" } • test.programmers query: { _id: "scotthernandez" } • test.programmers query: { _id: "scotthernandez" }
  • 42. Find by Range (test) • ds.find(Programmer.class).field("followers").greaterThan(0) • ds.find(Programmer.class).filter("followers >", 0) • ds.find(Programmer.class).field("since"). lessThan(sdf.parse("Jan 1, 2010"))
  • 43. Find by Range (logs) • test.programmers query: { followers: { $gt: 0 } } • test.programmers query: { followers: { $gt: 0 } } • test.programmers query: { memberSince: { $lt: new Date(1262322000000) } }
  • 45. Combining conditions (logs) test.programmers query: { memberSince: { $lt: new Date(1262322000000) }, followers: { $gt: 0 } }
  • 46. Find by Reference (test) ds.find(Repository.class).field("owner").equal(scott)
  • 47. Find by Reference (logs) test.repos query: { owner: { $ref: "programmers", $id: "scotthernandez" } }
  • 48. @Indexed • Annotation for fields – value (IndexDirection) – name (String) – unique (boolean) – dropDups (boolean) – background (boolean) – sparse (boolean) • Examples – @Indexed(value=IndexDirection.ASC, name="followers") int followers; – @Indexed @Reference(lazy = true) Repository forkedFrom;
  • 49. @Indexes and @Index • @Indexes: Annotation for types – value (Index[]) • @Index – value (String) – Others same as @Indexed • Examples – @Indexes(@Index("since, -followers")) public class Programmer {…}
  • 50. Updating with save (test) Programmer jeff = createJeff(); ds.save(jeff); // jeff is following scott, so increment // scott's followers and re-save Programmer scott = ds.get(Programmer.class, "scotthernandez") scott.followers++; ds.save(scott);
  • 51. Updating with save (logs) update test.programmers query: { _id: "scotthernandez", } update: { _id: "scotthernandez", className: "demo.Programmer", followers: 9, following: [ "moraes", "stickfigure" ], memberSince: new Date(1250049600000), active: true, name: "Scott Hernandez", }
  • 52. Updating with save (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "followers" : 9, "following" : [ "moraes", "stickfigure" ], "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "name" : "Scott Hernandez" }
  • 53. Optimistic Concurrency (model) @Entity public abstract class Member { @Id String userName; @Property("memberSince") Date since; boolean active; String name; @Version Long version; }
  • 54. Optimistic Concurrency (logs) update test.programmers query: { _id: "scotthernandez", version: 1345497713173 } update: { _id: "scotthernandez", className: "demo.Programmer", followers: 9, following: [ "moraes", "stickfigure" ], memberSince: new Date(1250049600000), active: true, name: "Scott Hernandez", version: 1345497718181 }
  • 55. Optimistic Concurrency (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "followers" : 9, "following" : [ "moraes", "stickfigure" ], "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "name" : "Scott Hernandez", "version" : NumberLong("1345497660444") }
  • 56. UpdateOperations (test) Programmer jeff = createJeff(); ds.save(jeff); // increment followers of scott by one UpdateOperations<Programmer> incrementFollowing = ds.createUpdateOperations(Programmer.class). inc("followers", 1); Query<Programmer> queryForScott = ds.find(Programmer.class, "userName", "scotthernandez"); ds.update(queryForScott, incrementFollowing);
  • 57. Web Resources • Morphia home: http://code.google.com/p/morphia/ • Morphia user group: https://groups.google.com/forum/?fromgroups#!forum/morphia • Demo code: https://github.com/jyemin/morphia-demo – Separate commit and tag for each slide, so you can play along
  • 58. Boston Resources • MongoDB User Group: http://www.meetup.com/Boston- MongoDB-User-Group/ • 10gen office hours: Monthly at Dog Patch (with yours truly)
  • 59. MongoDB Boston • October 23-24 – Oct 23: Workshops on Schema Design and Operations – Oct 24: Conference talks – Discount code: MUG10 for 10% off tickets – Early bird prices end Sept. 24 – Submit a talk proposal at 10gen.com/talk-proposal – URL: 10gen.com/events/mongodb-boston
  • 60. Thanks! • Jeff Yemin – https://twitter.com/@jeffyemin – jeff.yemin@10gen.com – https://github.com/jyemin/