Skip to content

Cassandra Specific Features

kkmishra edited this page May 9, 2013 · 20 revisions

Replication Factor

In order to set replication factor, just add below line into kundera-cassandra.xml:

<property name="replcation.factor" value="n" />

where 'n' is an integer number, e.g. 3

Placement Strategy

For setting placement strategy, add below line into kundera-cassandra.xml:

<property name="strategy.class" value="SimpleStrategy" />
OR
<property name="strategy.class" value="NetworkTopologyStrategy" />

Counter Column Family

Counter column families, available starting with Cassandra 0.8.0, are supported in Kundera. They are specified in Cassandra Client configuration file like this:

<table>
    <name>MyCounterColumnFamily1</name>
    <properties>
        <property name="default.validation.class" value="CounterColumnType"></property>
	<property name="key.validation.class" value="UTF8Type"></property>
    </properties>
</table>

Please note that Counter column family Name should be same as the table name specified at entity class definition, like this:

@Entity
@Table(name = "MyCounterColumnFamily1", schema = "KunderaExamples@cassandra_pu")
public class WebPageHitCounter
{
    @Id
    private String id;

    @Column
    private int counter;

    //getters and setters
}

For example on how to use this feature, refer to test class CountersTest and SuperCountersTest.

Inverted Indexing

As a default behavior, Kundera uses Cassandra's secondary indexing mechanism for querying on columns in a column family. A limitation of secondary indexing is that it doesn't support querying on columns within super columns.

To overcome this limitation, users have an option to use Lucene Indexing, which can be switched on by specifying "index.home.dir" property in persistence.xml. It enables users to run queries in column families as well as super column families.

For those who don't want to use Lucene indexing because of performance or other reasons, inverted indexing is an alternative. You can turn it on via specifying below property in XML file as:

<property name="inverted.indexing.enabled" value="true" />

It enables insertion of records in inverted index column family when user inserts records in the original column family. When you run JPA query for searching a column within a super column, Kundera searches in inverted index first, retrieves Row key, and then finds records from original column family.

For an example: See TwissandraTest.

CQL Version Setup

You can specify CQL version at either connection level (see XML at bottom) or operation level. Before running native queries (CQL in Cassandra), you can specify CQL version at operation level. Here is how to do it:

EntityManagerFactoryImpl emf = Persistence.createEntityManagerFactory("cassandra_pu");
EntityManager em = emf.createEntityManager();
        
Map<String, Client> clientMap = (Map<String, Client>) em.getDelegate();
PelopsClient pc = (PelopsClient)clientMap.get("cassandra_pu");
pc.setCqlVersion("3.0.0");  //Other possible value is 2.0.0

String nativeQuery = "SELECT * FROM users WHERE state='UT' AND birth_date > 1970";
Query q = em.createNativeQuery(nativeQuery, User.class);  //User is entity class
List<User> results = q.getResultList();

An example test case is available here.

Here is a sample XML configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<clientProperties>
    <datastores>
        <dataStore>
	    <name>cassandra</name>
            <connection>
	        <properties>
		    <property name="cql.version" value="3.0.0"></property>					
		</properties>
	    </connection>
	    <schemas>
	        <schema>
		    <name>KunderaCassandraXmlTest</name>
		    <properties>
		        <property name="strategy.class" value="SimpleStrategy" />
			<property name="replcation.factor" value="1" />
			<property name="durable.writes" value="true" />
                        <property name="inverted.indexing.enabled" value="true" />
		    </properties>
		    <dataCenters>
		        <dataCenter>
			    <name>DC1</name>
			    <value>3</value>
			</dataCenter>
			<dataCenter>
			    <name>DC2</name>
			    <value>2</value>
			</dataCenter>
		    </dataCenters>
		    <tables>
		        <table>
			    <name>USERXYZ</name>
			    <properties>
			        <property name="default.validation.class" value="UTF8Type"></property>
				<property name="key.validation.class" value="UTF8Type"></property>
				<property name="comment" value="User Column Family"></property>
				<property name="max.compaction.threshold" value="64"></property>
				<property name="min.compaction.threshold" value="16"></property>
				<property name="replicate.on.write" value="true"></property>
				<property name="comparator.type" value="UTF8Type"></property>
			    </properties>
			</table>
		    </tables>
		</schema>
	    </schemas>
	</dataStore>
    </datastores>
</clientProperties>

Switch from thrift to CQL Setup

If you switch from thrift to CQL then all CRUD operation will be executed through execute cql query, switch to CQL will resolve the problem on interoperability i.e. creating schema using cql and doing crud using kundera, if you want to switch from thrift to CQL, then you have to specify it on EntityManagerFactory creation level, Here is how to do it:

Map propertyMap = new HashMap();
propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0);
EntityManagerFactoryImpl emf = Persistence.createEntityManagerFactory("cassandra_pu",propertyMap);

<<< Back to Datastore Specific Configuration

Home

Clone this wiki locally