2 Getting Started - Reference Documentation
Authors: Paras Lakhani
Version: 5.0.8.RELEASE
Table of Contents
2 Getting Started
To get started with GORM for Cassandra you need configure it as a dependency inbuild.gradle
:dependencies { compile 'org.grails.plugins:cassandra:VERSION' }
dependencies { compile 'org.grails.plugins:cassandra:VERSION' compile("com.datastax.cassandra:cassandra-driver-core:2.0.4") compile "org.springframework.data:spring-data-commons:1.8.4.RELEASE" compile("org.springframework.data:spring-data-cassandra:1.0.4.RELEASE") { exclude group:'org.apache.cassandra',module:'cassandra-all' } }
CASSANDRA_HOME/bin/cassandra -f
INFO 00:11:16,935 Starting listening for CQL clients on localhost/127.0.0.1:9042… INFO 00:11:17,013 Using TFramedTransport with a max frame size of 15728640 bytes. INFO 00:11:17,014 Binding thrift service to localhost/127.0.0.1:9160 INFO 00:11:17,042 Using synchronous/threadpool thrift server on localhost : 9160 INFO 00:11:17,042 Listening for thrift clients...
grails-app/conf/application.yml
:grails: cassandra: contactPoints: localhost port: 9042 keyspace: name: foo } }
2.1 Using GORM for Cassandra Standalone
If you plan to use Cassandra as your primary datastore then you need to remove the Hibernate plugin from yourbuild.gradle
file.compile 'org.grails.plugins:hibernate'
create-domain-class
command:grails create-domain-class Person
Person
domain class will automatically be a persistent entity that can be stored in Cassandra. Example:class Person { String firstName String lastName } def person = new Person(firstName: "Fred", lastName: "Flintstone")person.save() … def person2 = Person.get(uuid)
2.2 Combining Cassandra and Hibernate
If you have both the Hibernate and Cassandra plugins installed then by default all classes in thegrails-app/domain
directory will be persisted by Hibernate and not Cassandra.
If you want to persist a particular domain class with Cassandra then you must use the mapWith
property in the domain class:static mapWith = "cassandra"
id
property of type Long
to your domain class. The Cassandra plugin adds an id
property of type UUID
.
If you install both plugins, the id
property will be of type Long
.
So if you have a domain class with an auto-generated id
(the default behaviour) and you want to save it to both datastores, you should define a UUID id
property as a Long
won't really work for Cassandra. You also need to set the id's generator
attribute so that the Hibernate plugin can auto-generate a UUID
.
2.3 Advanced Configuration
Cassandra Database Connection Configuration
As mentioned above, the GORM for Cassandra plugin will configure itself with default settings, but if you wish to customize those defaults you can do so in thegrails-app/conf/application.groovy
file:grails { cassandra { contactPoints = "localhost" port = 9042 schemaAction = "recreate-drop-unused" keyspace { name = "foo" action = "create" } } }
keyspace name
property configures the default keyspace to use. If it's not specified the keyspace
used will default to the name of your application.In production scenarios you will typically use more than one Cassandra node:grails {
cassandra {
contactPoints = "192.168.0.1, 192.168.0.2" //comma-separated list of hostnames or IP addresses of nodes to connect to
}
}
Keyspace creation
If you want the plugin to automatically create the application's keyspace you can specify a value for thekeyspace action
property:grails { cassandra { keyspace { name = "foo" action = "create" } } }
action
are:
- create - Create the keyspace if it doesn't exist
- create-drop - Drop the keyspace and create it if doesn't exist
Schema creation
The plugin can automatically create the Cassandra tables and indexes required for your domain model. You have some control over when and how it does this through thedbCreate
property, which can take these values:
- none - The default. Do not create any schema objects.
- create - Create a table and indexes for each domain class on startup. Fail if a table already exists.
- recreate - Create a table and indexes for each domain class on startup, dropping the table first if it exists.
- recreate-drop-unused - Drop all tables in the keyspace, then create a table and indexes for each domain class on startup.
- update - TO IMPLEMENT
grails {
cassandra {
dbCreate = "recreate-drop-unused"
}
}
Configuration Options Guide
Below is a complete example showing all configuration options, including keyspace options:grails { cassandra { contactPoints = "localhost" //comma-separated list of hostnames or IP addresses of nodes to connect to port = 9042 //the port to connect to dbCreate = "recreate" //the strategy to create cassandra tables and indexes for domain classes, default: "none" stateless = false // whether to use stateless sessions by default keyspace { name = "foo" //the name of the keyspace to use, default: the name of the application action = "create" //whether to create a keyspace, default: no keyspace created //keyspace properties to set only if the plugin is to create the keyspace durableWrites = false //default: false replicationStrategy = "SIMPLE_STRATEGY" OR "NETWORK_TOPOLOGY_STRATEGY" //default: "SIMPLE_STRATEGY" replicationFactor = 1 //default: 1 dataCenter = ["us-west":1, "eu-west":2] //if replicationStrategy is "NetworkTopologyStrategy", //a map of data centre names and replication factors } } }
Global Mapping Configuration
Using thegrails.cassandra.default.mapping
setting in application.groovy
you can configure global mapping options across your domain classes.
The following configuration will disable optimistic locking globally:grails.cassandra.default.mapping = { version false }
2.4 Using GORM in Spring Boot
To use GORM for Hibernate in Spring Boot add the necessary dependencies to your Boot application:compile("org.grails:gorm-cassandra-spring-boot:VERSION")
dependencies { compile("org.grails:gorm-cassandra-spring-boot:VERSION") compile("com.datastax.cassandra:cassandra-driver-core:2.0.4") compile "org.springframework.data:spring-data-commons:1.8.4.RELEASE" compile("org.springframework.data:spring-data-cassandra:1.0.4.RELEASE") { exclude group:'org.apache.cassandra',module:'cassandra-all' } }
Application
class is annotated with ComponentScan
, example:import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.context.annotation.*@Configuration @EnableAutoConfiguration @ComponentScan class Application { static void main(String[] args) { SpringApplication.run Application, args } }
UsingFinally create your GORM entities and ensure they are annotated withComponentScan
without a value results in Boot scanning for classes in the same package or any package nested within theApplication
class package. If your GORM entities are in a different package specify the package name as the value of theComponentScan
annotation.
grails.persistence.Entity
:import grails.persistence.*@Entity class Person { String firstName String lastName }
2.5 GORM for Cassandra outside Grails
If you wish to use GORM for Cassandra outside of a Grails application you should declare the necessary dependencies, for example in Gradle:compile "org.grails:grails-datastore-gorm-cassandra:VERSION"
grails.gorm.annotation.Entity
annotation:@Entity
class Person {
String name
}
CassandraDatastoreSpringInitializer
:def initializer = new CassandraDatastoreSpringInitializer(Person)
def applicationContext = initializer.configure()println Person.count()
org.springframework.core.env.PropertyResolver
interface:def initializer = new CassandraDatastoreSpringInitializer(['grails.cassandra.port':7891], Person)
def applicationContext = initializer.configure()println Person.count()
ApplicationContext
you can instead call configureForBeanDefinitionRegistry
prior to refreshing the context. You can pass the Spring Environment
object to the constructor for configuration:ApplicationContext myApplicationContext = …
def initializer = new CassandraDatastoreSpringInitializer(myApplicationContext.getEnvironment(), Person)
initializer.configureForBeanDefinitionRegistry(myApplicationContext)println Person.count()