Java straitjackets for
MongoDB
Alexey Zinovyev, Java Trainer
About
I am a <graph theory, machine learning,
traffic jams prediction, BigData algorithms>
scientist
But I'm a <Java, NoSQL, Hadoop, Spark>
programmer
Raise your hands if you ..
•use Hibernate & Spring
Raise your hands if you ..
•use Hibernate & Spring
• keep your data in MongoDB
Raise your hands if you ..
•use Hibernate & Spring
• keep your data in MongoDB
• use only Java Driver for Mongo
Raise your hands if you ..
•use Hibernate & Spring
• keep your data in MongoDB
• use only Java Driver for Mongo
• write your own mapping from Java objects to
BSON
7Joker 2015
Let’s do this with Mongo’D
8Joker 2015
The Good Old Days
9Joker 2015
One of these fine days...
10Joker 2015
We have a NoSQL job for you, son!
11Joker 2015
But you like SQL and HATE nontraditional data
12Joker 2015
Typical situation, isn’t it?
13Joker 2015
Let’s talk about it, Java - boy...
NOSQL
15Joker 2015
What’s the problem with RBDMS’s
• Caching
• Master/Slave
• Cluster
• Table Partitioning
• Sharding
16Joker 2015
Try to find
Mongo
17Joker 2015
Homo
Mongous
18Joker 2015
Fashion and trend
19Joker 2015
Gentle NoSQL
• Scalability
20Joker 2015
Gentle NoSQL
• Scalability
• Nodes and Data Centers
21Joker 2015
Gentle NoSQL
• Scalability
• Nodes and Data Centers
• Easy to add new server
22Joker 2015
Gentle NoSQL
• Scalability
• Nodes and Data Centers
• Easy to add new server
• Specific data model
23Joker 2015
Gentle NoSQL
• Scalability
• Nodes and Data Centers
• Easy to add new server
• Specific data model
• Eventual consistency
24Joker 2015
Comparison criteria
• Education curve
• Performance
• Drivers & frameworks
• Hadoop integration
• Mobile client
25Joker 2015
But what about .. “ACID”?
26Joker 2015
ACID in SQL
27Joker 2015
Atomicity in NoSQL
• read-write-modify (CAS)
• key/row manipulation is atomic
• API for atomic operations
• bad support of transactions (play with 2 phase commit)
28Joker 2015
BASE
• basic availability – all queries will be finished
• soft state – state can be changed without writing
• eventual consistency
MONGO DB
30Joker 2015
BSON (something like JSON)
• Adds data types that JSON did not support – (ISO Dates,
ObjectId, etc.)
• Optimized for performance
• Adds compression
31Joker 2015
Mongo: pro and contra
❏ Full-featured query
language
❏ Aggregation framework
❏ Big variety of indexes
❏ Replication and sharding
❏ Documentation
★ Limit for document size
(16 mb)
★ Complex cluster schema
★ No joins
32Joker 2015
Is Mongo terrible?
• Stability?
• JavaScript at the bottom
• Something new
• Low barrier for entry
• Easy to lose your data
DBA
programmer
34Joker 2015
The Database and programmers
JAVA DRIVER API
36Joker 2015
INSERT
Mongo mongo = new Mongo(…);
DB db = mongo.getDB("myDb");
Collection collection = db.getCollection(“customers");
37Joker 2015
INSERT
Mongo mongo = new Mongo(…);
DB db = mongo.getDB("myDb");
Collection collection = db.getCollection(“customers");
DBObject hotel = new BasicDBObject();
address.put(“name”, “ParkInn”);
38Joker 2015
INSERT
Mongo mongo = new Mongo(…);
DB db = mongo.getDB("myDb");
Collection collection = db.getCollection(“customers");
DBObject hotel = new BasicDBObject();
address.put(“name”, “ParkInn”);
DBObject person = new BasicDBObject();
person.put("firstname”, “Alexey”);
person.put("lastname”, “Zinoviev”);
person.put(“hotel”, hotel);
collection.save(person);
39Joker 2015
SELECT with Filter
DBObject query = new BasicDBObject();
query.put(“hotel.name”, “ParkInn”);
DBCursor cursor = collection.find(query);
for (DBObject element : cursor) {
// Map data onto object
}
40Joker 2015
Async call
41Joker 2015
But.. how about @ and JPA and ..
MORPHIA
43Joker 2015
Morphia
Object Document Mapper
• Specifed with annotations
• Implemented with reflection
• Runtime validation
44Joker 2015
Morphia advantages
• Integrated with Spring, Guice and other DI frameworks
45Joker 2015
Morphia advantages
• Integrated with Spring, Guice and other DI frameworks
• Lifecycle Method Annotations (@PrePersist, @PostLoad)
46Joker 2015
Morphia advantages
• Integrated with Spring, Guice and other DI frameworks
• Lifecycle Method Annotations (@PrePersist, @PostLoad)
• Built on top of Mongo Java Driver
47Joker 2015
Morphia advantages
• Integrated with Spring, Guice and other DI frameworks
• Lifecycle Method Annotations (@PrePersist, @PostLoad)
• Built on top of Mongo Java Driver
• More better than old-style queries by BSON-object
48Joker 2015
Morphia advantages
• Integrated with Spring, Guice and other DI frameworks
• Lifecycle Method Annotations (@PrePersist, @PostLoad)
• Built on top of Mongo Java Driver
• More better than old-style queries by BSON-object
• Query API: ds.createQuery(MyEntity.class)
.filter("foo >",12)
.order("date, -foo");
49Joker 2015
Model
@Entity(“customers")
class Customer {
@Id String taxId;
Date memberSince;
boolean active;
int followers;
List<String> following;
}
50Joker 2015
Model with embedded entity
@Entity(“customers")
class Customer {
@Id String taxId;
Name name;
Date memberSince;
boolean active;
int followers;
List<String> following;
}
@Embedded
class Name {
String first, last;
}
51Joker 2015
Save
Customer customer = new Customer();
customer.taxId = "zaleslaw";
customer.name = new Name("Alexey", "Zinoviev");
customer.memberSince = dateFmt.parse("Aug 12, 2009");
customer.active = true;
customer.followers = 8;
customer.following = Arrays.asList("Boris", "Tor");
ds.save(customer);
52Joker 2015
Read from database
> db.customers.findOne()
{
"_id" : “zaleslaw",
"className" : "demo.Customer",
"name" : {
"first" : "Alexey",
"last" : "Zinoviev"
},
"memberSince" : ISODate("2009-08-12T04:00:00Z"),
"active" : true,
"followers" : 8,
"following" : [
"Boris",
"Tor"
]
}
53Joker 2015
Find by filter
ds.find(Customer.class).
field("since").lessThan(dateFmt.parse("Jan 1, 2010")).
field("followers").greaterThan(0)
54Joker 2015
Polymorphism
public abstract class EmployeeEntity {
protected String name;
}
public class ManagerEntity extends EmployeeEntity {
protected Boolean approveFunds;
}
public class WorkerEntity extends EmployeeEntity {
protected Integer yearsExperience;
}
55Joker 2015
Polymorphism in RDBMs
56Joker 2015
Polymorphism in RDBMs
1. Union table with (many) NULL values
57Joker 2015
Polymorphism in RDBMs
1. Union table with (many) NULL values
2. Concrete instances without common queries
58Joker 2015
Polymorphism in RDBMs
1. Union table with (many) NULL values
2. Concrete instances without common queries
3. Base table joined with all subtables
59Joker 2015
Polymorphism with Morphia
@Entity(value = "employee", noClassnameStored = false)
public abstract class EmployeeEntity {
@Id
protected ObjectId id;
protected String name;
}
public class ManagerEntity extends EmployeeEntity {
protected Boolean approveFunds;
}
public class WorkerEntity extends EmployeeEntity {
protected Integer yearsExperience;
}
60Joker 2015
Meanwhile in Mongo
{
"_id": ObjectId("5461c8bf9e2acf32ed5ab079"),
"className": "entities.ManagerEntity",
"name": “Alex",
"approveFunds": true
}
{
"_id": ObjectId("524d9fe7e4b0f8bd3031f89e"),
"className": "entities.WorkerEntity",
"name": “Max",
"yearsExperience": 100
}
61Joker 2015
SELECTs
public EmployeeEntity findByEmail(final String email) {
return mongoDatastore.find(EmployeeEntity.class)
.field("email").equal(email).get();
}
public List<EmployeeEntity> getAllEmployees() {
return mongoDatastore.find(EmployeeEntity.class).asList();
}
public List<ManagerEntity> getAllManagers() {
return mongoDatastore.find(ManagerEntity.class)
.disableValidation()
.field("className").equal(ManagerEntity.class.getName())
.asList();
62Joker 2015
It’s Time for Java Superhero, yeah!
SPRING DATA
64Joker 2015
One faith, one Spring for ages!
65Joker 2015
Spring Data
• Templating : connection configs, collection lifecycle
(create, drop), Map/Reduce + Aggregation
• Mapping: @Document, @Index, @Field
• Repository support: geospatial queries, queries derived
from method signatures (at runtime)
• Paging, sorting, CRUD operations
66Joker 2015
All we need in configs
67Joker 2015
Advanced configs
<mongo:mongo host="${mongo.host}" port="${mongo.port}">
<mongo:options
connections-per-host="${mongo.connectionsPerHost}„
threads-allowed-to-block-for-connection
multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}„
connect-timeout="${mongo.connectTimeout}„
max-wait-time="${mongo.maxWaitTime}„
auto-connect-retry="${mongo.autoConnectRetry}„
socket-keep-alive="${mongo.socketKeepAlive}„
socket-timeout="${mongo.socketTimeout}„
slave-ok="${mongo.slaveOk}„
write-number="1„
write-timeout="0„
write-fsync="true"/>
</mongo:mongo>
<mongo:db-factorydbname= "test" mongo-ref="mongo"/>
68Joker 2015
Entity Mapping
@Document
class Customer {
@Id private BigInteger id;
@Indexed private String firstname, lastname;
@Field("email") private String emailAddress;
@DBRef private Set<Customer> contacts;
public Person(String firstname) { … }
@PersistenceConstructor
public Customer(String firstname, String lastname) { … }
…
}
69Joker 2015
Mongo operations
public interface MongoOperations {
// Generic callback-accepting methods
<T> T execute(DbCallback<T> action);
<T> T execute(Class<?> entityClass, CollectionCallback<T> action);
<T> T execute(String collectionName, CollectionCallback<T> action);
}
70Joker 2015
Mongo operations
public interface MongoOperations {
// Generic callback-accepting methods
<T> T execute(DbCallback<T> action);
<T> T execute(Class<?> entityClass, CollectionCallback<T> action);
<T> T execute(String collectionName, CollectionCallback<T> action);
// Higher level access methods
<T> List<T> find(Query query, Class<T> entityClass);
void save(Object objectToSave, String collectionName);
WriteResult updateFirst(Query query, Update update, Class<?>
entityClass);
}
71Joker 2015
Template usage
Mongo mongo = new Mongo();
MongoDbFactory factory = new SimpleMongoDbFactory(mongo, „customers“);
MongoTemplate template = new MongoTemplate(factory);
72Joker 2015
Template usage
Mongo mongo = new Mongo();
MongoDbFactory factory = new SimpleMongoDbFactory(mongo, „customers“);
MongoTemplate template = new MongoTemplate(factory);
Customer me = new Customer (“Alexey", “Zinoviev");
me.setEmailAddress(“Alexey_Zinovyeve@epam.com");
template.save(me);
73Joker 2015
Template usage
Mongo mongo = new Mongo();
MongoDbFactory factory = new SimpleMongoDbFactory(mongo, „customers“);
MongoTemplate template = new MongoTemplate(factory);
Customer me = new Customer (“Alexey", “Zinoviev");
me.setEmailAddress(“Alexey_Zinovyeve@epam.com");
template.save(me);
Query query = new Query(new Criteria("emailAddress")
.is("Alexey_Zinovyeve@epam.com"));
assertThat(template.find(query), is(me));
74Joker 2015
Spring Repositories : it does all job
• Uses a method-naming convention that Spring interprets
during implementation
• Hides complexities of Spring Data templates
• Builds implementation for you based on interface design
• Implementation is built during Spring container load.
75Joker 2015
Typical JPA Repository
public interface PersonRepository extends Repository<Person, BigInteger>
{
// Finder for a single entity
Person findByEmailAddress(String emailAddress);
// Finder for multiple entities
List<Person> findByLastnameLike(String lastname);
// Finder with pagination
Page<Person> findByFirstnameLike(String firstname, Pageable page);
}
76Joker 2015
Mongo Repository
public interface PersonRepository extends Repository<Person, BigInteger>
{
// Finder for a single entity
Person findByEmailAddress(String emailAddress);
// Finder for multiple entities
List<Person> findByLastnameLike(String lastname);
// Finder with pagination
Page<Person> findByFirstnameLike(String firstname, Pageable page);
// Geospatial queries
List<Person> findByLocationNear(Point location, Distance distance);
GeoResults<Person> findByLocationNear(Point location);
}
77Joker 2015
Let’s autowire it!
@Component
public class MyClient {
@Autowired
private PersonRepository repository;
public List<Person> doSomething() {
Point point = new Point(55.7, 70.8);
Distance distance = new Distance(200, Metrics.KILOMETERS);
return repository.findByLocationNear(point, distance);
}
}
JONGO
79Joker 2015
Jongo
• Jackson and BSON4Jackson for (Un)marshalling
• No JPA / Hibernate style
• Query in Java as in Mongo Shell
80Joker 2015
Jongo : find
db.users.find( { $or : [ { age : {$gt:20,$lt:30} } ,
{ age : {$gt:50,$lt:60} } ] } )
Iterable<User> users = collection.find ("{ $or : [ { age :
{$gt:20,$lt:30} } , { age : {$gt:50,$lt:60} } ] } ").as(User.class);
81Joker 2015
Java Driver API
DB db = mongo.getDB("users");
DBCollection collection = db.getCollection("users");
DBObject firstQuery = QueryBuilder.start("age").greaterThan(20).lessThan(30).get();
DBObject secondQuery = QueryBuilder.start("age").greaterThan(50).lessThan(60).get();
DBObject query = QueryBuilder.start().or(firstQuery,secondQuery).get();
DBCursor results = collection.find(query);
List<User> users = new ArrayList<User>();
for (DBObject result : results) {
User user = new User();
user.setUsername((String) result.get("username"));
user.setAge((Integer) result.get("age"));
users.add(user);
}
82Joker 2015
Jongo : aggregation
MongoCollection collection = new Jongo(db).getCollection("emails");
collection.aggregate(“ {$project:{sender:1}} ")
.and(“ {$match:{tags:'read'}} ")
.and(“ {$limit:10} ")
.as(Email.class);
WHAT ABOUT
HIBERNATE?
84Joker 2015
Hibernate in NoSQL world (by Hibernate opinion)
85Joker 2015
Hibernate in NoSQL world (in reality)
86Joker 2015
Hibernate OGM
• Java Persistence (JPA) support for NoSQL solutions
• JP-QL queries are converted in native backend queries
• Hibernate Search as indexing engine and use full-text
queries
• You can call flush(), commit() and demarcate transactions
• It supports only MongoDB, Neo4j, Infinispan, Ehcache
87Joker 2015
Data cycle
88Joker 2015
OGM mapping
@Entity
@NamedQuery(
name="byItemsQuantity",
query = "SELECT o FROM Order o JOIN o.items i WHERE i.quantity = :quantity"
)
public class Order {
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Id private String id;
private Date date;
@Column(name = "custInfo") private String customerInfo;
@ElementCollection
private List<Item> items;
POLYGLOT PERSISTANCE
90Joker 2015
Different databases in one project
• RBDMS: Needs transactional updates and has tabular structure
• Riak: Needs high availability across multiple locations. Can merge
inconsistent writes
• MongoDB: Lots of reads, infrequent writes. Powerful aggregation
mechanism
• Cassandra: Large-scale analytics on large cluster. High volume of
writes on multiple nodes
91Joker 2015
Your application, isn’t it?
92Joker 2015
Kundera
• Atomicity guarantee and Transaction management
• Strictly JPA 2.1 compatible
• It supports Cassandra, Mongo, Hbase, Redis, Neo4j and etc
• @Embedded and @ElementCollection for ColumnFamily and nested
documents
• OneToMany, OneToOne, ManyToMany relationships
• Not full JPQL support for different database
93Joker 2015
Kundera
94Joker 2015
It solves all problems!
IN CONCLUSION
96Joker 2015
Other tools
• EclipseLink : different support of different NoSQL
databases
• MJORM : Google Code, XML mapping + MQL (SQL syntax
for Mongo data extracting)
• DataNucleus : support many J as JDO, JPA
97Joker 2015
Abstraction vs Standardization
98Joker 2015
In conclusion
• Think about your data
99Joker 2015
In conclusion
• Think about your data
• Understand you project needs
100Joker 2015
In conclusion
• Think about your data
• Understand you project needs
• Choose right framework
101Joker 2015
In conclusion
• Think about your data
• Understand you project needs
• Choose right framework
• Know & use MongoDB features
102Joker 2015
Listen to your heart … DATA
103Joker 2015
CALL ME
IF YOU WANT TO KNOW MORE
Thanks a lot
104Joker 2015
Contacts
E-mail : Alexey_Zinovyev@epam.com
Twitter : @zaleslaw
LinkedIn: https://www.linkedin.com/in/zaleslaw

Joker'15 Java straitjackets for MongoDB

  • 1.
  • 2.
    About I am a<graph theory, machine learning, traffic jams prediction, BigData algorithms> scientist But I'm a <Java, NoSQL, Hadoop, Spark> programmer
  • 3.
    Raise your handsif you .. •use Hibernate & Spring
  • 4.
    Raise your handsif you .. •use Hibernate & Spring • keep your data in MongoDB
  • 5.
    Raise your handsif you .. •use Hibernate & Spring • keep your data in MongoDB • use only Java Driver for Mongo
  • 6.
    Raise your handsif you .. •use Hibernate & Spring • keep your data in MongoDB • use only Java Driver for Mongo • write your own mapping from Java objects to BSON
  • 7.
    7Joker 2015 Let’s dothis with Mongo’D
  • 8.
  • 9.
    9Joker 2015 One ofthese fine days...
  • 10.
    10Joker 2015 We havea NoSQL job for you, son!
  • 11.
    11Joker 2015 But youlike SQL and HATE nontraditional data
  • 12.
  • 13.
    13Joker 2015 Let’s talkabout it, Java - boy...
  • 14.
  • 15.
    15Joker 2015 What’s theproblem with RBDMS’s • Caching • Master/Slave • Cluster • Table Partitioning • Sharding
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
    20Joker 2015 Gentle NoSQL •Scalability • Nodes and Data Centers
  • 21.
    21Joker 2015 Gentle NoSQL •Scalability • Nodes and Data Centers • Easy to add new server
  • 22.
    22Joker 2015 Gentle NoSQL •Scalability • Nodes and Data Centers • Easy to add new server • Specific data model
  • 23.
    23Joker 2015 Gentle NoSQL •Scalability • Nodes and Data Centers • Easy to add new server • Specific data model • Eventual consistency
  • 24.
    24Joker 2015 Comparison criteria •Education curve • Performance • Drivers & frameworks • Hadoop integration • Mobile client
  • 25.
    25Joker 2015 But whatabout .. “ACID”?
  • 26.
  • 27.
    27Joker 2015 Atomicity inNoSQL • read-write-modify (CAS) • key/row manipulation is atomic • API for atomic operations • bad support of transactions (play with 2 phase commit)
  • 28.
    28Joker 2015 BASE • basicavailability – all queries will be finished • soft state – state can be changed without writing • eventual consistency
  • 29.
  • 30.
    30Joker 2015 BSON (somethinglike JSON) • Adds data types that JSON did not support – (ISO Dates, ObjectId, etc.) • Optimized for performance • Adds compression
  • 31.
    31Joker 2015 Mongo: proand contra ❏ Full-featured query language ❏ Aggregation framework ❏ Big variety of indexes ❏ Replication and sharding ❏ Documentation ★ Limit for document size (16 mb) ★ Complex cluster schema ★ No joins
  • 32.
    32Joker 2015 Is Mongoterrible? • Stability? • JavaScript at the bottom • Something new • Low barrier for entry • Easy to lose your data
  • 33.
  • 34.
  • 35.
  • 36.
    36Joker 2015 INSERT Mongo mongo= new Mongo(…); DB db = mongo.getDB("myDb"); Collection collection = db.getCollection(“customers");
  • 37.
    37Joker 2015 INSERT Mongo mongo= new Mongo(…); DB db = mongo.getDB("myDb"); Collection collection = db.getCollection(“customers"); DBObject hotel = new BasicDBObject(); address.put(“name”, “ParkInn”);
  • 38.
    38Joker 2015 INSERT Mongo mongo= new Mongo(…); DB db = mongo.getDB("myDb"); Collection collection = db.getCollection(“customers"); DBObject hotel = new BasicDBObject(); address.put(“name”, “ParkInn”); DBObject person = new BasicDBObject(); person.put("firstname”, “Alexey”); person.put("lastname”, “Zinoviev”); person.put(“hotel”, hotel); collection.save(person);
  • 39.
    39Joker 2015 SELECT withFilter DBObject query = new BasicDBObject(); query.put(“hotel.name”, “ParkInn”); DBCursor cursor = collection.find(query); for (DBObject element : cursor) { // Map data onto object }
  • 40.
  • 41.
    41Joker 2015 But.. howabout @ and JPA and ..
  • 42.
  • 43.
    43Joker 2015 Morphia Object DocumentMapper • Specifed with annotations • Implemented with reflection • Runtime validation
  • 44.
    44Joker 2015 Morphia advantages •Integrated with Spring, Guice and other DI frameworks
  • 45.
    45Joker 2015 Morphia advantages •Integrated with Spring, Guice and other DI frameworks • Lifecycle Method Annotations (@PrePersist, @PostLoad)
  • 46.
    46Joker 2015 Morphia advantages •Integrated with Spring, Guice and other DI frameworks • Lifecycle Method Annotations (@PrePersist, @PostLoad) • Built on top of Mongo Java Driver
  • 47.
    47Joker 2015 Morphia advantages •Integrated with Spring, Guice and other DI frameworks • Lifecycle Method Annotations (@PrePersist, @PostLoad) • Built on top of Mongo Java Driver • More better than old-style queries by BSON-object
  • 48.
    48Joker 2015 Morphia advantages •Integrated with Spring, Guice and other DI frameworks • Lifecycle Method Annotations (@PrePersist, @PostLoad) • Built on top of Mongo Java Driver • More better than old-style queries by BSON-object • Query API: ds.createQuery(MyEntity.class) .filter("foo >",12) .order("date, -foo");
  • 49.
    49Joker 2015 Model @Entity(“customers") class Customer{ @Id String taxId; Date memberSince; boolean active; int followers; List<String> following; }
  • 50.
    50Joker 2015 Model withembedded entity @Entity(“customers") class Customer { @Id String taxId; Name name; Date memberSince; boolean active; int followers; List<String> following; } @Embedded class Name { String first, last; }
  • 51.
    51Joker 2015 Save Customer customer= new Customer(); customer.taxId = "zaleslaw"; customer.name = new Name("Alexey", "Zinoviev"); customer.memberSince = dateFmt.parse("Aug 12, 2009"); customer.active = true; customer.followers = 8; customer.following = Arrays.asList("Boris", "Tor"); ds.save(customer);
  • 52.
    52Joker 2015 Read fromdatabase > db.customers.findOne() { "_id" : “zaleslaw", "className" : "demo.Customer", "name" : { "first" : "Alexey", "last" : "Zinoviev" }, "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "followers" : 8, "following" : [ "Boris", "Tor" ] }
  • 53.
    53Joker 2015 Find byfilter ds.find(Customer.class). field("since").lessThan(dateFmt.parse("Jan 1, 2010")). field("followers").greaterThan(0)
  • 54.
    54Joker 2015 Polymorphism public abstractclass EmployeeEntity { protected String name; } public class ManagerEntity extends EmployeeEntity { protected Boolean approveFunds; } public class WorkerEntity extends EmployeeEntity { protected Integer yearsExperience; }
  • 55.
  • 56.
    56Joker 2015 Polymorphism inRDBMs 1. Union table with (many) NULL values
  • 57.
    57Joker 2015 Polymorphism inRDBMs 1. Union table with (many) NULL values 2. Concrete instances without common queries
  • 58.
    58Joker 2015 Polymorphism inRDBMs 1. Union table with (many) NULL values 2. Concrete instances without common queries 3. Base table joined with all subtables
  • 59.
    59Joker 2015 Polymorphism withMorphia @Entity(value = "employee", noClassnameStored = false) public abstract class EmployeeEntity { @Id protected ObjectId id; protected String name; } public class ManagerEntity extends EmployeeEntity { protected Boolean approveFunds; } public class WorkerEntity extends EmployeeEntity { protected Integer yearsExperience; }
  • 60.
    60Joker 2015 Meanwhile inMongo { "_id": ObjectId("5461c8bf9e2acf32ed5ab079"), "className": "entities.ManagerEntity", "name": “Alex", "approveFunds": true } { "_id": ObjectId("524d9fe7e4b0f8bd3031f89e"), "className": "entities.WorkerEntity", "name": “Max", "yearsExperience": 100 }
  • 61.
    61Joker 2015 SELECTs public EmployeeEntityfindByEmail(final String email) { return mongoDatastore.find(EmployeeEntity.class) .field("email").equal(email).get(); } public List<EmployeeEntity> getAllEmployees() { return mongoDatastore.find(EmployeeEntity.class).asList(); } public List<ManagerEntity> getAllManagers() { return mongoDatastore.find(ManagerEntity.class) .disableValidation() .field("className").equal(ManagerEntity.class.getName()) .asList();
  • 62.
    62Joker 2015 It’s Timefor Java Superhero, yeah!
  • 63.
  • 64.
    64Joker 2015 One faith,one Spring for ages!
  • 65.
    65Joker 2015 Spring Data •Templating : connection configs, collection lifecycle (create, drop), Map/Reduce + Aggregation • Mapping: @Document, @Index, @Field • Repository support: geospatial queries, queries derived from method signatures (at runtime) • Paging, sorting, CRUD operations
  • 66.
    66Joker 2015 All weneed in configs
  • 67.
    67Joker 2015 Advanced configs <mongo:mongohost="${mongo.host}" port="${mongo.port}"> <mongo:options connections-per-host="${mongo.connectionsPerHost}„ threads-allowed-to-block-for-connection multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}„ connect-timeout="${mongo.connectTimeout}„ max-wait-time="${mongo.maxWaitTime}„ auto-connect-retry="${mongo.autoConnectRetry}„ socket-keep-alive="${mongo.socketKeepAlive}„ socket-timeout="${mongo.socketTimeout}„ slave-ok="${mongo.slaveOk}„ write-number="1„ write-timeout="0„ write-fsync="true"/> </mongo:mongo> <mongo:db-factorydbname= "test" mongo-ref="mongo"/>
  • 68.
    68Joker 2015 Entity Mapping @Document classCustomer { @Id private BigInteger id; @Indexed private String firstname, lastname; @Field("email") private String emailAddress; @DBRef private Set<Customer> contacts; public Person(String firstname) { … } @PersistenceConstructor public Customer(String firstname, String lastname) { … } … }
  • 69.
    69Joker 2015 Mongo operations publicinterface MongoOperations { // Generic callback-accepting methods <T> T execute(DbCallback<T> action); <T> T execute(Class<?> entityClass, CollectionCallback<T> action); <T> T execute(String collectionName, CollectionCallback<T> action); }
  • 70.
    70Joker 2015 Mongo operations publicinterface MongoOperations { // Generic callback-accepting methods <T> T execute(DbCallback<T> action); <T> T execute(Class<?> entityClass, CollectionCallback<T> action); <T> T execute(String collectionName, CollectionCallback<T> action); // Higher level access methods <T> List<T> find(Query query, Class<T> entityClass); void save(Object objectToSave, String collectionName); WriteResult updateFirst(Query query, Update update, Class<?> entityClass); }
  • 71.
    71Joker 2015 Template usage Mongomongo = new Mongo(); MongoDbFactory factory = new SimpleMongoDbFactory(mongo, „customers“); MongoTemplate template = new MongoTemplate(factory);
  • 72.
    72Joker 2015 Template usage Mongomongo = new Mongo(); MongoDbFactory factory = new SimpleMongoDbFactory(mongo, „customers“); MongoTemplate template = new MongoTemplate(factory); Customer me = new Customer (“Alexey", “Zinoviev"); me.setEmailAddress(“Alexey_Zinovyeve@epam.com"); template.save(me);
  • 73.
    73Joker 2015 Template usage Mongomongo = new Mongo(); MongoDbFactory factory = new SimpleMongoDbFactory(mongo, „customers“); MongoTemplate template = new MongoTemplate(factory); Customer me = new Customer (“Alexey", “Zinoviev"); me.setEmailAddress(“Alexey_Zinovyeve@epam.com"); template.save(me); Query query = new Query(new Criteria("emailAddress") .is("Alexey_Zinovyeve@epam.com")); assertThat(template.find(query), is(me));
  • 74.
    74Joker 2015 Spring Repositories: it does all job • Uses a method-naming convention that Spring interprets during implementation • Hides complexities of Spring Data templates • Builds implementation for you based on interface design • Implementation is built during Spring container load.
  • 75.
    75Joker 2015 Typical JPARepository public interface PersonRepository extends Repository<Person, BigInteger> { // Finder for a single entity Person findByEmailAddress(String emailAddress); // Finder for multiple entities List<Person> findByLastnameLike(String lastname); // Finder with pagination Page<Person> findByFirstnameLike(String firstname, Pageable page); }
  • 76.
    76Joker 2015 Mongo Repository publicinterface PersonRepository extends Repository<Person, BigInteger> { // Finder for a single entity Person findByEmailAddress(String emailAddress); // Finder for multiple entities List<Person> findByLastnameLike(String lastname); // Finder with pagination Page<Person> findByFirstnameLike(String firstname, Pageable page); // Geospatial queries List<Person> findByLocationNear(Point location, Distance distance); GeoResults<Person> findByLocationNear(Point location); }
  • 77.
    77Joker 2015 Let’s autowireit! @Component public class MyClient { @Autowired private PersonRepository repository; public List<Person> doSomething() { Point point = new Point(55.7, 70.8); Distance distance = new Distance(200, Metrics.KILOMETERS); return repository.findByLocationNear(point, distance); } }
  • 78.
  • 79.
    79Joker 2015 Jongo • Jacksonand BSON4Jackson for (Un)marshalling • No JPA / Hibernate style • Query in Java as in Mongo Shell
  • 80.
    80Joker 2015 Jongo :find db.users.find( { $or : [ { age : {$gt:20,$lt:30} } , { age : {$gt:50,$lt:60} } ] } ) Iterable<User> users = collection.find ("{ $or : [ { age : {$gt:20,$lt:30} } , { age : {$gt:50,$lt:60} } ] } ").as(User.class);
  • 81.
    81Joker 2015 Java DriverAPI DB db = mongo.getDB("users"); DBCollection collection = db.getCollection("users"); DBObject firstQuery = QueryBuilder.start("age").greaterThan(20).lessThan(30).get(); DBObject secondQuery = QueryBuilder.start("age").greaterThan(50).lessThan(60).get(); DBObject query = QueryBuilder.start().or(firstQuery,secondQuery).get(); DBCursor results = collection.find(query); List<User> users = new ArrayList<User>(); for (DBObject result : results) { User user = new User(); user.setUsername((String) result.get("username")); user.setAge((Integer) result.get("age")); users.add(user); }
  • 82.
    82Joker 2015 Jongo :aggregation MongoCollection collection = new Jongo(db).getCollection("emails"); collection.aggregate(“ {$project:{sender:1}} ") .and(“ {$match:{tags:'read'}} ") .and(“ {$limit:10} ") .as(Email.class);
  • 83.
  • 84.
    84Joker 2015 Hibernate inNoSQL world (by Hibernate opinion)
  • 85.
    85Joker 2015 Hibernate inNoSQL world (in reality)
  • 86.
    86Joker 2015 Hibernate OGM •Java Persistence (JPA) support for NoSQL solutions • JP-QL queries are converted in native backend queries • Hibernate Search as indexing engine and use full-text queries • You can call flush(), commit() and demarcate transactions • It supports only MongoDB, Neo4j, Infinispan, Ehcache
  • 87.
  • 88.
    88Joker 2015 OGM mapping @Entity @NamedQuery( name="byItemsQuantity", query= "SELECT o FROM Order o JOIN o.items i WHERE i.quantity = :quantity" ) public class Order { @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid2") @Id private String id; private Date date; @Column(name = "custInfo") private String customerInfo; @ElementCollection private List<Item> items;
  • 89.
  • 90.
    90Joker 2015 Different databasesin one project • RBDMS: Needs transactional updates and has tabular structure • Riak: Needs high availability across multiple locations. Can merge inconsistent writes • MongoDB: Lots of reads, infrequent writes. Powerful aggregation mechanism • Cassandra: Large-scale analytics on large cluster. High volume of writes on multiple nodes
  • 91.
  • 92.
    92Joker 2015 Kundera • Atomicityguarantee and Transaction management • Strictly JPA 2.1 compatible • It supports Cassandra, Mongo, Hbase, Redis, Neo4j and etc • @Embedded and @ElementCollection for ColumnFamily and nested documents • OneToMany, OneToOne, ManyToMany relationships • Not full JPQL support for different database
  • 93.
  • 94.
  • 95.
  • 96.
    96Joker 2015 Other tools •EclipseLink : different support of different NoSQL databases • MJORM : Google Code, XML mapping + MQL (SQL syntax for Mongo data extracting) • DataNucleus : support many J as JDO, JPA
  • 97.
  • 98.
    98Joker 2015 In conclusion •Think about your data
  • 99.
    99Joker 2015 In conclusion •Think about your data • Understand you project needs
  • 100.
    100Joker 2015 In conclusion •Think about your data • Understand you project needs • Choose right framework
  • 101.
    101Joker 2015 In conclusion •Think about your data • Understand you project needs • Choose right framework • Know & use MongoDB features
  • 102.
    102Joker 2015 Listen toyour heart … DATA
  • 103.
    103Joker 2015 CALL ME IFYOU WANT TO KNOW MORE Thanks a lot
  • 104.
    104Joker 2015 Contacts E-mail :Alexey_Zinovyev@epam.com Twitter : @zaleslaw LinkedIn: https://www.linkedin.com/in/zaleslaw