Important Subprojects
• grails-datastore-core!
– Core low level API
• grails-datastore-gorm!
– GORM API layer
• grails-datastore-gorm-tck!
– Test Suite
8
Contribute to GORM
• GORM is huge and sprawling
• Covers loads of data stores
• Great area to contribute to the
community. Some ideas:
• Multi Tenancy
• Elastic Search
• Hadoop / HBase
10
What is GORM Standalone?
• Easy initialisation of GORM outside of Grails
• And a set of Spring Boot plugins
• Required modularisation of codebase
• Reduction of external dependencies
• Simplification of GORM setup
12
Slide 13
Slide 13 text
Standalone Entities
• Annotated with grails.persistence.Entity
13
@Entity
class
Person
{
String
name
static
constraints
=
{
name
blank:false
}
}
Slide 14
Slide 14 text
GORM for Hibernate Standalone
• https://gist.github.com/graemerocher/c25ec929d9bcd1adcbea
14
@Grab("org.grails:grails-‐datastore-‐gorm-‐hibernate4:3.1.2.RELEASE")
@Grab("com.h2database:h2:1.3.164")
!
import
grails.orm.bootstrap.*
!
init
=
new
HibernateDatastoreSpringInitializer(Person)
def
dataSource
=
new
DriverManagerDataSource(Driver.name,
"jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALS
E",
'sa',
'')
init.configureForDataSource(dataSource)
Slide 15
Slide 15 text
GORM for MongoDB Standalone
• https://gist.github.com/graemerocher/9683650
15
@Grab("org.grails:grails-‐datastore-‐gorm-‐mongodb:3.0.2.RELEASE")
!
import
grails.mongodb.bootstrap.*
!
init
=
new
MongoDbDataStoreSpringInitializer(Person)
init.configure()
GORM for Hibernate in Spring Boot
• Add gorm-hibernate4-spring-boot as a dependency
!
!
!
!
• Then add persistent entities that are annotated with
grails.persistence.Entity
17
compile
"org.grails:gorm-‐hibernate4-‐
spring-‐boot:1.0.0.RELEASE"
Slide 18
Slide 18 text
GORM for MongoDB in Spring Boot
• Add gorm-mongodb-spring-boot as a dependency
!
!
!
!
• Then add persistent entities that are annotated with
grails.persistence.Entity
18
compile
"org.grails:gorm-‐mongodb-‐spring-‐
boot:1.1.0.RELEASE"
Hibernate Column Formula
• A column can be a read-only formula
25
class
Product
{
Float
price
Float
taxRate
Float
tax
static
mapping
=
{
tax
formula:
'PRICE
*
TAX_RATE'
}
}
Slide 26
Slide 26 text
Hibernate Column Readers/Writers
• New in 2.4: Implement custom column readers and writers
to transform data when written or read from the database.
26
class
Name
{
String
title
static
mapping
=
{
title
write:'UPPER(?)',
read:'REPEAT(title,
2)'
}
}
Slide 27
Slide 27 text
Asynchronous GORM
• Database operations are blocking
• Can be helpful to isolate these blocking operations on a
separately managed thread
• Work underway in some NoSQL datastore on fully
asynchronous drivers (MongoDB, CouchDB etc.)
• No usable asynchronous SQL/JDBC drivers on the horizon
(to my knowledge)
27
GORM for MongoDB
• Geospacial querying
• GeoJSON models
• Full text search
• Schemaless domain models
• Projections via MongoDB
aggregation
• Stateless and Stateful modes
• Custom user types
32
Slide 33
Slide 33 text
GORM for MongoDB Internals
• MongoEntityPersister implements persistence
• MongoQuery implements querying aggregation
• MongoSession implements batch inserts, updates and
deletes
• MongoGormStaticApi adds extra GORM methods
• GeoJSONType and subclasses implement GeoJSON
custom types
• https://github.com/grails/grails-data-mapping/tree/master/
grails-datastore-gorm-mongodb
33
Slide 34
Slide 34 text
GORM, MongoDB & GeoJSON
• Geo Data in MongoDB represented by GeoJSON types
– http://geojson.org
• Package grails.mongodb.geo contains GeoJSON
types
– Point, Polygon, LineString, MultiPoint,
MultiLineString, MultiPolygon,
GeometryCollection
34
Slide 35
Slide 35 text
Geospacial Querying
35
def
point
=
new
Point(2,
1)
def
p
=
new
Place(point:
point)
!
def
poly1
=
Polygon
.valueOf([
[0.0,
0.0],
[3.0,
0.0],
[3.0,
3.0],
[0.0,
3.0],
[0.0,
0.0]
])
!
Place.findByPointGeoWithin(poly1)
Slide 36
Slide 36 text
MongoDB Text Search
• Create text indices and use methods
36
Product.search('"Coffee
Cake"')
.size()
==
1
Product.searchTop("cake").size()
==
4
Product.searchTop("cake",3).size()
==
3
Product.countHits('coffee')
==
5
Slide 37
Slide 37 text
Schemaless Dynamic Properties
• Add dynamic properties with the subscript operator
37
def
p
=
new
Plant(name:"Pineapple")
p.save()
p["color"]
=
"Yellow"
p["hasLeaves"]
=
true
Hibernate in Unit Tests
• Add a dependency on grails-datastore-test-
support
!
!
!
• Provides HibernateTestMixin that will load Hibernate
inside a unit test
41
test
"org.grails:grails-‐datastore-‐test-‐
support:1.0-‐grails-‐2.4"
Slide 42
Slide 42 text
Hibernate in Unit Tests
42
import
grails.test.mixin.TestMixin
import
grails.test.mixin.gorm.Domain
import
grails.test.mixin.hibernate.*
import
spock.lang.Specification
!
@Domain(Person)
@TestMixin(HibernateTestMixin)
class
PersonSpec
extends
Specification
{
…
}
Slide 43
Slide 43 text
Summary
• GORM provides a rich and diverse ecosystem
• Goes far beyond relational databases
• Can be used standalone or within Grails
• Great area to contribute to!
43