31. Working with NoSQL technologies

Spring Data provides additional projects that help you access a variety of NoSQL technologies including MongoDB, Neo4J, Elasticsearch, Solr, Redis, Gemfire, Couchbase and Cassandra. Spring Boot provides auto-configuration for Redis, MongoDB, Neo4j, Elasticsearch, Solr and Cassandra; you can make use of the other projects, but you will need to configure them yourself. Refer to the appropriate reference documentation at projects.spring.io/spring-data.

31.1 Redis

Redis is a cache, message broker and richly-featured key-value store. Spring Boot offers basic auto-configuration for the Jedis client library and abstractions on top of it provided by Spring Data Redis. There is a spring-boot-starter-data-redis ‘Starter POM’ for collecting the dependencies in a convenient way.

31.1.1 Connecting to Redis

You can inject an auto-configured RedisConnectionFactory, StringRedisTemplate or vanilla RedisTemplate instance as you would any other Spring Bean. By default the instance will attempt to connect to a Redis server using localhost:6379:

@Component
public class MyBean {

    private StringRedisTemplate template;

    @Autowired
    public MyBean(StringRedisTemplate template) {
        this.template = template;
    }

    // ...

}

If you add a @Bean of your own of any of the auto-configured types it will replace the default (except in the case of RedisTemplate the exclusion is based on the bean name ‘redisTemplate’ not its type). If commons-pool2 is on the classpath you will get a pooled connection factory by default.

31.2 MongoDB

MongoDB is an open-source NoSQL document database that uses a JSON-like schema instead of traditional table-based relational data. Spring Boot offers several conveniences for working with MongoDB, including the spring-boot-starter-data-mongodb ‘Starter POM’.

31.2.1 Connecting to a MongoDB database

You can inject an auto-configured org.springframework.data.mongodb.MongoDbFactory to access Mongo databases. By default the instance will attempt to connect to a MongoDB server using the URL mongodb://localhost/test:

import org.springframework.data.mongodb.MongoDbFactory;
import com.mongodb.DB;

@Component
public class MyBean {

    private final MongoDbFactory mongo;

    @Autowired
    public MyBean(MongoDbFactory mongo) {
        this.mongo = mongo;
    }

    // ...

    public void example() {
        DB db = mongo.getDb();
        // ...
    }

}

You can set spring.data.mongodb.uri property to change the URL and configure additional settings such as the replica set:

spring.data.mongodb.uri=mongodb://user:[email protected]:12345,mongo2.example.com:23456/test

Alternatively, as long as you’re using Mongo 2.x, specify a host/port. For example, you might declare the following in your application.properties:

spring.data.mongodb.host=mongoserver
spring.data.mongodb.port=27017
[Note]Note

spring.data.mongodb.host and spring.data.mongodb.port are not supported if you’re using the Mongo 3.0 Java driver. In such cases, spring.data.mongodb.uri should be used to provide all of the configuration.

[Tip]Tip

If spring.data.mongodb.port is not specified the default of 27017 is used. You could simply delete this line from the sample above.

[Tip]Tip

If you aren’t using Spring Data Mongo you can inject com.mongodb.Mongo beans instead of using MongoDbFactory.

You can also declare your own MongoDbFactory or Mongo bean if you want to take complete control of establishing the MongoDB connection.

31.2.2 MongoTemplate

Spring Data Mongo provides a MongoTemplate class that is very similar in its design to Spring’s JdbcTemplate. As with JdbcTemplate Spring Boot auto-configures a bean for you to simply inject:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final MongoTemplate mongoTemplate;

    @Autowired
    public MyBean(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    // ...

}

See the MongoOperations Javadoc for complete details.

31.2.3 Spring Data MongoDB repositories

Spring Data includes repository support for MongoDB. As with the JPA repositories discussed earlier, the basic principle is that queries are constructed for you automatically based on method names.

In fact, both Spring Data JPA and Spring Data MongoDB share the same common infrastructure; so you could take the JPA example from earlier and, assuming that City is now a Mongo data class rather than a JPA @Entity, it will work in the same way.

package com.example.myapp.domain;

import org.springframework.data.domain.*;
import org.springframework.data.repository.*;

public interface CityRepository extends Repository<City, Long> {

    Page<City> findAll(Pageable pageable);

    City findByNameAndCountryAllIgnoringCase(String name, String country);

}
[Tip]Tip

For complete details of Spring Data MongoDB, including its rich object mapping technologies, refer to their reference documentation.

31.2.4 Embedded Mongo

Spring Boot offers auto-configuration for Embedded Mongo. To use it in your Spring Boot application add a dependency on de.flapdoodle.embed:de.flapdoodle.embed.mongo.

The port that Mongo will listen on can be configured using the spring.data.mongodb.port property. To use a randomly allocated free port use a value of zero. The MongoClient created by MongoAutoConfiguration will be automatically configured to use the randomly allocated port.

If you have SLF4J on the classpath, output produced by Mongo will be automatically routed to a logger named org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo.

You can declare your own IMongodConfig and IRuntimeConfig beans to take control of the Mongo instance’s configuration and logging routing.

31.3 Neo4j

Neo4j is an open-source NoSQL graph database that uses a rich data model of nodes related by first class relationships which is better suited for connected big data than traditional rdbms approaches. Spring Boot offers several conveniences for working with Neo4j, including the spring-boot-starter-data-neo4j ‘Starter POM’.

31.3.1 Connecting to a Neo4j database

You can inject an auto-configured Neo4jSession, Session or Neo4jOperations instance as you would any other Spring Bean. By default the instance will attempt to connect to a Neo4j server using localhost:7474:

@Component
public class MyBean {

    private final Neo4jTemplate neo4jTemplate;

    @Autowired
    public MyBean(Neo4jTemplate neo4jTemplate) {
        this.neo4jTemplate = neo4jTemplate;
    }

    // ...

}

You can take full control of the configuration by adding a org.neo4j.ogm.config.Configuration @Bean of your own. Also, adding a @Bean of type Neo4jOperations disables the auto-configuration.

You can configure the user and credentials to use via the spring.data.neo4j.* properties:

spring.data.neo4j.uri=http://my-server:7474
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=secret

31.3.2 Using the embedded mode

[Note]Note

Neo4j’s embedded mode is subject to a different licensing, make sure to review it before integrating the dependency in your application.

If you add org.neo4j:neo4j-ogm-embedded-driver to the dependencies of your application, Spring Boot will automatically configure an in-process embedded instance of Neo4j that will not persist any data when your application shuts down. You can explicitly disable that mode using spring.data.neo4j.embedded.enabled=false. You can also enable persistence for the embedded mode:

	spring.data.neo4j.uri=file://var/tmp/graph.db

31.3.3 Neo4jSession

By default, the lifetime of the session is scope to the application. If you are running a web application you can change it to scope or request easily:

	spring.data.neo4j.session.scope=session

31.3.4 Spring Data Neo4j repositories

Spring Data includes repository support for Neo4j.

In fact, both Spring Data JPA and Spring Data Neo4j share the same common infrastructure; so you could take the JPA example from earlier and, assuming that City is now a Neo4j OGM @NodeEntity rather than a JPA @Entity, it will work in the same way.

[Tip]Tip

You can customize entity scanning locations using the @NodeEntityScan annotation.

To enable repository support (and optionally support for @Transactional), add the following two annotations to your Spring configuration:

@EnableNeo4jRepositories(basePackages = "com.example.myapp.repository")
@EnableTransactionManagement

31.3.5 Repository example

package com.example.myapp.domain;

import org.springframework.data.domain.*;
import org.springframework.data.repository.*;

public interface CityRepository extends GraphRepository<City> {

    Page<City> findAll(Pageable pageable);

    City findByNameAndCountry(String name, String country);

}
[Tip]Tip

For complete details of Spring Data Neo4j, including its rich object mapping technologies, refer to their reference documentation.

31.4 Gemfire

Spring Data Gemfire provides convenient Spring-friendly tools for accessing the Pivotal Gemfire data management platform. There is a spring-boot-starter-data-gemfire ‘Starter POM’ for collecting the dependencies in a convenient way. There is currently no auto-configuration support for Gemfire, but you can enable Spring Data Repositories with a single annotation (@EnableGemfireRepositories).

31.5 Solr

Apache Solr is a search engine. Spring Boot offers basic auto-configuration for the Solr 5 client library and abstractions on top of it provided by Spring Data Solr. There is a spring-boot-starter-data-solr ‘Starter POM’ for collecting the dependencies in a convenient way.

31.5.1 Connecting to Solr

You can inject an auto-configured SolrClient instance as you would any other Spring bean. By default the instance will attempt to connect to a server using localhost:8983/solr:

@Component
public class MyBean {

    private SolrClient solr;

    @Autowired
    public MyBean(SolrClient solr) {
        this.solr = solr;
    }

    // ...

}

If you add a @Bean of your own of type SolrClient it will replace the default.

31.5.2 Spring Data Solr repositories

Spring Data includes repository support for Apache Solr. As with the JPA repositories discussed earlier, the basic principle is that queries are constructed for you automatically based on method names.

In fact, both Spring Data JPA and Spring Data Solr share the same common infrastructure; so you could take the JPA example from earlier and, assuming that City is now a @SolrDocument class rather than a JPA @Entity, it will work in the same way.

[Tip]Tip

For complete details of Spring Data Solr, refer to their reference documentation.

31.6 Elasticsearch

Elasticsearch is an open source, distributed, real-time search and analytics engine. Spring Boot offers basic auto-configuration for the Elasticsearch and abstractions on top of it provided by Spring Data Elasticsearch. There is a spring-boot-starter-data-elasticsearch ‘Starter POM’ for collecting the dependencies in a convenient way.

31.6.1 Connecting to Elasticsearch

You can inject an auto-configured ElasticsearchTemplate or Elasticsearch Client instance as you would any other Spring Bean. By default the instance will embed a local in-memory server (a Node in ElasticSearch terms) and use the current working directory as the home directory for the server. In this setup, the first thing to do is to tell ElasticSearch were to store its files:

spring.data.elasticsearch.properties.path.home=/foo/bar

Alternatively, you can switch to a remote server (i.e. a TransportClient) by setting spring.data.elasticsearch.cluster-nodes to a comma-separated ‘host:port’ list.

spring.data.elasticsearch.cluster-nodes=localhost:9300
@Component
public class MyBean {

    private ElasticsearchTemplate template;

    @Autowired
    public MyBean(ElasticsearchTemplate template) {
        this.template = template;
    }

    // ...

}

If you add a @Bean of your own of type ElasticsearchTemplate it will replace the default.

31.6.2 Spring Data Elasticsearch repositories

Spring Data includes repository support for Elasticsearch. As with the JPA repositories discussed earlier, the basic principle is that queries are constructed for you automatically based on method names.

In fact, both Spring Data JPA and Spring Data Elasticsearch share the same common infrastructure; so you could take the JPA example from earlier and, assuming that City is now an Elasticsearch @Document class rather than a JPA @Entity, it will work in the same way.

[Tip]Tip

For complete details of Spring Data Elasticsearch, refer to their reference documentation.

31.7 Cassandra

Cassandra is an open source, distributed database management system designed to handle large amounts of data across many commodity servers. Spring Boot offers auto-configuration for Cassandra and abstractions on top of it provided by Spring Data Cassandra. There is a spring-boot-starter-data-cassandra ‘Starter POM’ for collecting the dependencies in a convenient way.

31.7.1 Connecting to Cassandra

You can inject an auto-configured CassandraTemplate or a Cassandra Session instance as you would with any other Spring Bean. The spring.data.cassandra.* properties can be used to customize the connection. Generally you will provide keyspace-name and contact-points properties:

spring.data.cassandra.keyspace-name=mykeyspace
spring.data.cassandra.contact-points=cassandrahost1,cassandrahost2
@Component
public class MyBean {

    private CassandraTemplate template;

    @Autowired
    public MyBean(CassandraTemplate template) {
        this.template = template;
    }

    // ...

}

If you add a @Bean of your own of type CassandraTemplate it will replace the default.

31.7.2 Spring Data Cassandra repositories

Spring Data includes basic repository support for Cassandra. Currently this is more limited than the JPA repositories discussed earlier, and will need to annotate finder methods with @Query.

[Tip]Tip

For complete details of Spring Data Cassandra, refer to their reference documentation.

31.8 Couchbase

Couchbase is an open-source, distributed multi-model NoSQL document-oriented database that is optimized for interactive applications. Spring Boot offers auto-configuration for Couchbase and abstractions on top of it provided by Spring Data Couchbase. There is a spring-boot-starter-data-couchbase ‘Starter POM’ for collecting the dependencies in a convenient way.

31.8.1 Connecting to Couchbase

You can very easily get a Bucket and Cluster by adding the Couchbase SDK and some configuration. The spring.couchbase.* properties can be used to customize the connection. Generally you will provide the bootstrap hosts, bucket name and password:

spring.couchbase.bootstrap-hosts=my-host-1,192.168.1.123
spring.couchbase.bucket.name=my-bucket
spring.couchbase.bucket.password=secret
[Tip]Tip

You need to provide at least the bootstrap host(s), in which case the bucket name is default and the password is the empty String. Alternatively, you can define your own org.springframework.data.couchbase.config.CouchbaseConfigurer @Bean to take control over the whole configuration.

It is also possible to customize some of the CouchbaseEnvironment settings. For instance the following configuration changes the timeout to use to open a new Bucket and enable SSL support:

spring.couchbase.env.timeouts.connect=3000
spring.couchbase.env.ssl.key-store=/location/of/keystore.jks
spring.couchbase.env.ssl.key-store-password=secret

Check the spring.couchbase.env.* properties for more details.

31.8.2 Spring Data Couchbase repositories

Spring Data includes repository support for Couchbase. For complete details of Spring Data Couchbase, refer to their reference documentation.

You can inject an auto-configured CouchbaseTemplate instance as you would with any other Spring Bean as long as a default CouchbaseConfigurer is available (that happens when you enable the couchbase support as explained above). If you want to bypass the auto-configuration for Spring Data Couchbase, provide your own org.springframework.data.couchbase.config.AbstractCouchbaseDataConfiguration implementation.

@Component
public class MyBean {

    private final CouchbaseTemplate template;

    @Autowired
    public MyBean(CouchbaseTemplate template) {
        this.template = template;
    }

    // ...

}

If you add a @Bean of your own of type CouchbaseTemplate named couchbaseTemplate it will replace the default.