5 Stateless Mode - Reference Documentation
Authors: Graeme Rocher, Burt Beckwith
Version: 5.0.8.RELEASE
5 Stateless Mode
GORM for MongoDB supports both stateless and stateful modes for mapping domain classes to MongoDB. In general stateful mapping is superior for write heavy applications and stateless mode better for read heavy applications (particularily when large amounts of data is involved).Stateful mode
Domain classes are by default stateful, which means when they are read from a MongoDB document their state is stored in the user session (which is typically bound to the request in Grails). This has several advantages for write heavy applications:- GORM can automatically detect whether a call to save() is a an update or an insert and act appropriately
- GORM stores the state of the read MongoDB document and therefore updates to schemaless properties don't require an extra query
- GORM can store the current version and therefore implement optimistic locking
- Repeated reads of the same entity can be retrieved from the cache, thus optimizing reads as well
def b = Book.get(1)
b['pages'] = 400
b['publisher'] = 'Manning'
b['rating'] = 5
b.save(flush:true)Stateless Domain classes
However, stateful domain classes can cause problems for read-heavy applications. Take for example the following code:def books = Book.list() // read 100,000 books
for(b in books) {
println b.title
}Book.withStatelessSession {
def books = Book.list() // read 100,000 books
for(b in books) {
println b.title
}
}class Book {
…
static mapping = {
stateless true
}
}Disadvantages of Stateless Mode
There are several disadvantages to using stateless domain classes as the default. One disadvantage is that if you are using assigned identifiers GORM cannot detect whether you want to do an insert or an update so you have to be explicit about which one you want:def b = new Book(id:"The Book") b.insert()
def books = Book.list() // read 100,000 books
for(b in books) {
println b['pages']
println b['rating']
}def books = Book.list() // read 100,000 books
for(b in books) {
def dbo = b.dbo
println dbo['pages']
println dbo['rating']
}def books = Book.collection.find() // read 100,000 books
for(dbo in books) {
Book b = dbo as Book
println dbo['pages']
println dbo['rating']
}