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 withComponentScanwithout a value results in Boot scanning for classes in the same package or any package nested within theApplicationclass package. If your GORM entities are in a different package specify the package name as the value of theComponentScanannotation.
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()