{"id":2039,"date":"2015-12-16T19:37:00","date_gmt":"2015-12-16T19:37:00","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2039"},"modified":"2024-09-12T01:12:09","modified_gmt":"2024-09-12T08:12:09","slug":"couchbase-spring-cache","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/","title":{"rendered":"Backing Spring Cache With Couchbase"},"content":{"rendered":"<p><!-- Backing Spring Cache with Couchbase --><\/p>\n<p>In this blog post, we&#8217;ll discover how to cache data easily using <code>Spring Cache<\/code> and <code>Couchbase<\/code> as a backing store manager.<\/p>\n<p><strong>Table of Contents<\/strong><br \/>\n<!-- TOC depth:6 withLinks:1 updateOnSave:1 orderedList:0 --><\/p>\n<ul>\n<li><a href=\"#a-word-of-introduction\">A Word Of Introduction<\/a><\/li>\n<li><a href=\"#the-cache-abstraction\">The <code>Cache<\/code> Abstraction<\/a><\/li>\n<li><a href=\"#the-couchbase-implementation\">The Couchbase Implementation<\/a><\/li>\n<li><a href=\"#getting-couchbase-spring-cache-and-putting-it-to-work\">Getting <code>couchbase-spring-cache<\/code> and Putting it to Work<\/a>\n<ul>\n<li><a href=\"#downloading-and-building-the-couchbase-spring-cache-project\">Downloading and building the <code>couchbase-spring-cache<\/code> project<\/a><\/li>\n<li><a href=\"#starting-a-tutorial-project\">Starting a Tutorial Project<\/a><\/li>\n<li><a href=\"#add-book-management-entity-and-repository\">Add Book Management Entity and Repository<\/a><\/li>\n<li><a href=\"#the-main-spring-boot-application\">The Main <code>Spring Boot<\/code> Application<\/a><\/li>\n<li><a href=\"#adding-caching-capabilities\">Adding Caching Capabilities<\/a><\/li>\n<li><a href=\"#activate-caching-in-simplebookrepository\">Activate Caching in <code>SimpleBookRepository<\/code><\/a><\/li>\n<li><a href=\"#seeing-the-data-in-couchbase\">Seeing the Data in Couchbase<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#conclusion\">Conclusion<\/a><br \/>\n<!-- \/TOC --><\/li>\n<\/ul>\n<h2 id=\"a-word-of-introduction\">A Word Of Introduction<\/h2>\n<p>There was a lot of work related to <code>Spring<\/code> lately! We&#8217;ve been busy working on the <code><a href=\"https:\/\/docs.couchbase.com\/sdk-extensions\/spring-data-couchbase.html\">Spring Data Couchbase<\/a><\/code> connector to upgrade it to the 2.x generation of the Java SDK, bringing along <a href=\"https:\/\/www.couchbase.com\/blog\/spring-data-couchbase-2.0-preview\/\" target=\"_blank\" rel=\"noopener noreferrer\">a host of new features and improvements<\/a> (but more on that in a later blog post)&#8230;<\/p>\n<p>Along the way, it came to our attention that there are a few classes in the project that are not really related directly to <code>Spring Data<\/code> and as such didn&#8217;t need to adhere to its formal &#8220;Release Train&#8221; release cycle: <strong>the <code>cache<\/code> package<\/strong>.<\/p>\n<p>So we started a new simple Spring Boot Cache example project to host <strong>the <code>2.x<\/code> generation of the <code>Couchbase Spring Cache<\/code> implementation<\/strong> on github (<a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-spring-cache\" target=\"_blank\" rel=\"noopener noreferrer\"><code>couchbaselabs\/couchbase-spring-cache<\/code><\/a>).<\/p>\n<p>Let&#8217;s have a look at how it can be leveraged to easily introduce Couchbase-backed caching into a Spring project!<\/p>\n<h2 id=\"the-cache-abstraction\">The <code>Cache<\/code> Abstraction<\/h2>\n<p>Spring Framework comes with a lightweight abstraction of a <code>Cache<\/code> that developers can automatically use by annotating methods in their classes (eg. in a <code>@Repository<\/code> stereotype).<\/p>\n<p>In order to make use of Spring\u2019s boot caching mechanisms, you simply annotate your methods with a handful of cache-related annotations:<\/p>\n<ul>\n<li><code>@Cacheable<\/code> will let the first invocation of the annotated method with a particular set of input parameters execute, but the result will be cached and subsequent invocations (with the same set) will be served transparently from the cache.<\/li>\n<li><code>@CachePut<\/code> will always invoke the method and cache its result (unlike <code>@Cacheable<\/code> it doesn&#8217;t optimize the invocation flow).<\/li>\n<li><code>@CacheEvict<\/code> will compute a cache key from the annotated method&#8217;s parameters and remove it from the cache when the method is executed (eg. because invoking this method makes an entry stale).<\/li>\n<li><code>@Caching<\/code> allows to regroup behavior from the previous annotation into a single one.<\/li>\n<li><code>@CacheConfig<\/code> allows us to have common cache parameters set on a whole class.<\/li>\n<\/ul>\n<h2 id=\"the-couchbase-implementation\">The Couchbase Implementation<\/h2>\n<p>The abstract mechanism is put in place by the framework, but an actual backing implementation must be chosen. Spring comes with a few of them (in memory <code>Map<\/code>, <code>EhCache<\/code>, <code>Gemfire<\/code>&#8230;), but it is absolutely possible to define custom ones, <strong>simply by implementing a <code>Cache<\/code> and a <code>CacheManager<\/code> and making it visible in the Spring context<\/strong>.<\/p>\n<p>That&#8217;s the focus of <code>couchbase-spring-cache<\/code>.<\/p>\n<p>Each cache has a name, and each value in the cache has a cache key. The Couchbase implementation will translate that into a document key that reflects that&#8230;<\/p>\n<ul>\n<li>this is a <code>Cache<\/code> related document (by default using the prefix &#8220;<code>cache:<\/code>&#8220;)<\/li>\n<li>it relates to a particular <code>Cache<\/code> (by adding the <code>CACHE_NAME<\/code> to the prefix above)<\/li>\n<li>it stores a particular cache value under <code>CACHE_KEY<\/code> (so all in all &#8220;<strong><code>cache:CACHE_NAME:CACHE_KEY<\/code><\/strong>&#8220;).<\/li>\n<\/ul>\n<p>For now the values must be <code>Serializable<\/code> and are stored as a <code>SerializableDocument<\/code> from the <code>2.x<\/code> Java SDK, but alternative transcoding could be offered in the future, eg. <code>JSON<\/code>\/<code>JsonDocument<\/code>&#8230;<\/p>\n<h2 id=\"getting-couchbase-spring-cache-and-putting-it-to-work\">Getting <code>couchbase-spring-cache<\/code> and Putting it to Work<\/h2>\n<p>Note:<\/p>\n<blockquote><p>As of this writing the project is currently in <code>1.0-SNAPSHOT<\/code> version so it is not available on <code>Maven Central<\/code> yet. You&#8217;ll have to manually build the jar and add it to your local Maven repository.<\/p><\/blockquote>\n<h2 id=\"downloading-and-building-the-couchbase-spring-cache-project\">Downloading and building the <code>couchbase-spring-cache<\/code> project<\/h2>\n<p>Start by cloning the project from github:<\/p>\n<pre class=\"bash\"><code>git clone https:\/\/github.com\/couchbaselabs\/couchbase-spring-cache.git\r\ncd couchbase-spring-cache<\/code><\/pre>\n<p>Then build and install it locally using Maven:<\/p>\n<pre class=\"bash\"><code>mvn clean install<\/code><\/pre>\n<p>You should see a success message indicating the version built and where it was installed:<\/p>\n<pre>[INFO] Installing \/path\/to\/couchbase-spring-cache\/target\/couchbase-spring-cache-<span style=\"background-color: yellow\">1.0-SNAPSHOT.jar<\/span>\r\n\r\nto <span style=\"background-color: orange\">\/path\/to\/.m2\/repository\/<\/span><span style=\"background-color: lightgrey\">com\/couchbase\/client\/couchbase-spring-cache\/1.0-SNAPSHOT\/couchbase-spring-cache-1.0-SNAPSHOT.jar<\/span>\r\n\r\n[INFO] Installing \/path\/to\/couchbase-spring-cache\/pom.xml\r\n\r\nto \/path\/to\/.m2\/repository\/com\/couchbase\/client\/couchbase-spring-cache\/1.0-SNAPSHOT\/couchbase-spring-cache-1.0-SNAPSHOT.pom\r\n\r\n[INFO] ------------------------------------------------------------------------\r\n\r\n[INFO] BUILD SUCCESS\r\n\r\n[INFO] ------------------------------------------------------------------------\r\n\r\n<\/pre>\n<h2 id=\"starting-a-tutorial-project\">Starting a Tutorial Project<\/h2>\n<p>We&#8217;ll build a Spring Cache example project using Maven and <code>Spring Boot<\/code> as a base.<br \/>\nStart by creating the following directory structure for the project in a root directory of your choosing (we&#8217;ll use <code>cbcache<\/code> here):<\/p>\n<pre><code> cbcache\r\n    \u2514\u2500\u2500 src\r\n        \u2514\u2500\u2500 main\r\n            \u2514\u2500\u2500 java\r\n                \u2514\u2500\u2500 com\r\n                    \u2514\u2500\u2500 couchbase\r\n                        \u2514\u2500\u2500 demo<\/code><\/pre>\n<p>For instance, use the following command:<\/p>\n<pre class=\"bash\"><code>mkdir -p cbcache\/src\/main\/java\/com\/couchbase\/demo\/\r\ncd cbcache<\/code><\/pre>\n<p>Then initiate the POM at the cbcache root in <code>pom.xml<\/code> with the following content:<\/p>\n<pre class=\"xml\"><code><!--?xml version=\"1.0\" encoding=\"UTF-8\"?-->\r\n\r\n    4.0.0\r\n\r\n    com.couchbase.demo\r\n    cbcache\r\n    0.1.0\r\n\r\n    \r\n        org.springframework.boot\r\n        spring-boot-starter-parent\r\n        1.3.0.RELEASE\r\n    \r\n\r\n    \r\n        1.8\r\n    \r\n\r\n    \r\n        \r\n            org.springframework.boot\r\n            spring-boot-starter\r\n        \r\n        \r\n            org.springframework\r\n            spring-context\r\n        \r\n        <!--the couchbase cache artifact we built earlier-->\r\n        \r\n            com.couchbase.client\r\n            couchbase-spring-cache\r\n            1.0-SNAPSHOT\r\n        \r\n    \r\n\r\n    \r\n        \r\n            \r\n                org.springframework.boot\r\n                spring-boot-maven-plugin\r\n            \r\n        \r\n    \r\n\r\n<\/code><\/pre>\n<h2 id=\"add-book-management-entity-and-repository\">Add Book Management Entity and Repository<\/h2>\n<p>We&#8217;ll use the example of a <code>Book<\/code> repository (as found in the &#8220;<a href=\"https:\/\/spring.io\/guides\/gs\/caching\/\">GETTING STARTED &#8211; Caching Data with Spring<\/a>&#8221; official guide from Spring.io).<\/p>\n<p>Create the <code>Book<\/code> entity class in <code>src\/main\/java\/com\/couchbase\/demo\/Book.java<\/code>:<\/p>\n<pre class=\"java\"><code>import java.io.Serializable;\r\n\r\npublic class Book implements Serializable {\r\n\r\n    private static final long serialVersionUID = -7674163614777124381L;\r\n\r\n    private String isbn;\r\n    private String title;\r\n\r\n    public Book(String isbn, String title) {\r\n        this.isbn = isbn;\r\n        this.title = title;\r\n    }\r\n\r\n    public String getIsbn() {\r\n        return isbn;\r\n    }\r\n\r\n    public void setIsbn(String isbn) {\r\n        this.isbn = isbn;\r\n    }\r\n\r\n    public String getTitle() {\r\n        return title;\r\n    }\r\n\r\n    public void setTitle(String title) {\r\n        this.title = title;\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        return \"Book{\" + \"isbn='\" + isbn + ''' + \", title='\" + title + ''' + '}';\r\n    }\r\n}<\/code><\/pre>\n<blockquote><p>Note the <code>Book<\/code> class is <code>Serializable<\/code>, this is important for now for Couchbase storage.<\/p><\/blockquote>\n<p>Create a simple repository interface and a naive implementation that simulates a delay:<\/p>\n<p>in <code>src\/main\/java\/com\/couchbase\/demo\/BookRepository.java<\/code>:<\/p>\n<pre class=\"java\"><code>package com.couchbase.demo;\r\n\r\npublic interface BookRepository {\r\n\r\n    Book getByIsbn(String isbn);\r\n\r\n}<\/code><\/pre>\n<p>in <code>src\/main\/java\/com\/couchbase\/demo\/SimpleBookRepository.java<\/code>:<\/p>\n<pre class=\"java\"><code>package com.couchbase.demo;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport org.springframework.stereotype.Component;\r\n\r\n@Component\r\npublic class SimpleBookRepository implements BookRepository {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(SimpleBookRepository.class);\r\n\r\n    @Override\r\n    public Book getByIsbn(String isbn) {\r\n        simulateSlowService();\r\n        Book result = new Book(isbn, \"Some book\");\r\n        log.info(\"Actual fetch of \" + isbn);\r\n        return result;\r\n    }\r\n\r\n    \/\/ Don't do this at home\r\n    private void simulateSlowService() {\r\n        try {\r\n            long time = 5000L;\r\n            Thread.sleep(time);\r\n        } catch (InterruptedException e) {\r\n            throw new IllegalStateException(e);\r\n        }\r\n    }\r\n\r\n}<\/code><\/pre>\n<h2 id=\"the-main-spring-boot-application\">The Main <code>Spring Boot<\/code> Application<\/h2>\n<p>Finally, create an Application that uses the repository in <code>src\/main\/java\/com\/couchbase\/demo\/Application.java<\/code>:<\/p>\n<pre class=\"java\"><code>package com.couchbase.demo;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.boot.CommandLineRunner;\r\nimport org.springframework.boot.SpringApplication;\r\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\r\nimport org.springframework.stereotype.Component;\r\n\r\n@SpringBootApplication\r\npublic class Application {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(Application.class);\r\n\r\n    @Component\r\n    static class Runner implements CommandLineRunner {\r\n        @Autowired\r\n        private BookRepository bookRepository;\r\n\r\n        @Override\r\n        public void run(String... args) throws Exception {\r\n            long start;\r\n            log.info(\".... Fetching books\");\r\n            fetchAndLog(\"isbn-1234\");\r\n            fetchAndLog(\"isbn-1234\");\r\n            fetchAndLog(\"isbn-1234\");\r\n            fetchAndLog(\"isbn-8888\");\r\n            fetchAndLog(\"isbn-8888\");\r\n        }\r\n\r\n        private void fetchAndLog(String isbn) {\r\n            long start = System.currentTimeMillis();\r\n            Book book = bookRepository.getByIsbn(isbn);\r\n            long time = System.currentTimeMillis() - start;\r\n            log.info(isbn + \" --&gt; \" + book + \" in \" + time + \"ms\");\r\n        }\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        SpringApplication.run(Application.class, args);\r\n    }\r\n}<\/code><\/pre>\n<p>If you run the <code>Application<\/code>&#8216;s <code>main<\/code> method in your IDE (or if you invoke &#8220;<code>mvn spring-boot:run<\/code>&#8221; from the command line), you&#8217;ll notice that all the calls are indeed quite slow:<\/p>\n<pre class=\"txt\"><code>[...] .... Fetching books\r\n[...] Actual fetch of isbn-1234\r\n[...] isbn-1234 --&gt; Book{isbn='isbn-1234', title='Some book'} in 5001ms\r\n[...] Actual fetch of isbn-1234\r\n[...] isbn-1234 --&gt; Book{isbn='isbn-1234', title='Some book'} in 5004ms\r\n[...] Actual fetch of isbn-1234\r\n[...] isbn-1234 --&gt; Book{isbn='isbn-1234', title='Some book'} in 5004ms\r\n[...] Actual fetch of isbn-8888\r\n[...] isbn-8888 --&gt; Book{isbn='isbn-8888', title='Some book'} in 5003ms\r\n[...] Actual fetch of isbn-8888\r\n[...] isbn-8888 --&gt; Book{isbn='isbn-8888', title='Some book'} in 5003ms<\/code><\/pre>\n<h2 id=\"adding-caching-capabilities\">Adding Spring Boot Caching Capabilities<\/h2>\n<p>In order to enable caching, you must take a few steps: first you must offer Spring a <code>CacheManager<\/code> <code>@Bean<\/code>&#8230;<\/p>\n<p>Since we&#8217;ll be using the <code>CouchbaseCacheManager<\/code> (of course), we&#8217;ll need to connect to a <code>Cluster<\/code> and use a <code>Bucket<\/code> reference (the storage unit where couchbase will store cache documents).<br \/>\nSo the <code>CouchbaseCacheManager<\/code> needs a mapping between <code>Cache<\/code> names and the corresponding <code>Bucket<\/code> to use, passed as a <code>Map&lt;String, Bucket&gt;<\/code>.<\/p>\n<p>In <code>src\/main\/java\/com\/couchbase\/demo\/Application.java<\/code>, add the following bean declarations:<\/p>\n<pre class=\"java\"><code>  public static final String BOOK_CACHE = \"books\";\r\n\r\n  @Bean(destroyMethod = \"disconnect\")\r\n  public Cluster cluster() {\r\n      \/\/this connects to a Couchbase instance running on localhost\r\n      return CouchbaseCluster.create();\r\n  }\r\n\r\n  @Bean(destroyMethod = \"close\")\r\n  public Bucket bucket() {\r\n      \/\/this will be the bucket where every cache-related data will be stored\r\n      \/\/note that the bucket \"default\" must exist\r\n      return cluster().openBucket(\"default\", \"\");\r\n  }\r\n\r\n  @Bean\r\n  public CacheManager cacheManager() {\r\n      Map&lt;String, Bucket&gt; mapping = new HashMap&lt;String, Bucket&gt;();\r\n      \/\/we'll make this cache manager recognize a single cache named \"books\"\r\n      mapping.put(BOOK_CACHE, bucket());\r\n      return new CouchbaseCacheManager(mapping);\r\n  }<\/code><\/pre>\n<p>You then want to activate the scanning of cache-related annotations and associated proxying by putting the <code>@EnableCaching<\/code> annotation on the <code>Application<\/code> class.<\/p>\n<h2 id=\"activate-caching-in-simplebookrepository\">Activate Caching in <code>SimpleBookRepository<\/code><\/h2>\n<p>Let&#8217;s see how to activate actual caching on our <code>SimpleBookRepository<\/code> and verify how the application behaves after that.<\/p>\n<p>To make <code>getByIsbn<\/code> automatically cache on first invocation and serve subsequent invocations with data from the cache, simply annotate it like so:<\/p>\n<pre class=\"java\"><code>    @Override\r\n    @Cacheable(Application.BOOK_CACHE) \/\/using the name of the cache we declared earlier\r\n    public Book getByIsbn(String isbn) {\r\n        simulateSlowService();\r\n        Book result = new Book(isbn, \"Some book\");\r\n        log.info(\"Actual fetch of \" + isbn);\r\n        return result;\r\n    }<\/code><\/pre>\n<p>Let&#8217;s run the application again and see how it behaves now:<\/p>\n<pre class=\"txt\"><code>[...] .... Fetching books\r\n[...] Actual fetch of isbn-1234\r\n[...] isbn-1234 --&gt; Book{isbn='isbn-1234', title='Some book'} in 5022ms\r\n[...] isbn-1234 --&gt; Book{isbn='isbn-1234', title='Some book'} in 3ms\r\n[...] isbn-1234 --&gt; Book{isbn='isbn-1234', title='Some book'} in 1ms\r\n[...] Actual fetch of isbn-8888\r\n[...] isbn-8888 --&gt; Book{isbn='isbn-8888', title='Some book'} in 5007ms\r\n[...] isbn-8888 --&gt; Book{isbn='isbn-8888', title='Some book'} in 1ms<\/code><\/pre>\n<p>Wow! This is much better for invocations past the first one, looks like it is indeed cached :-)<\/p>\n<h2 id=\"seeing-the-data-in-couchbase\">Seeing the Data in Couchbase<\/h2>\n<p>Let&#8217;s have a quick look at the webconsole to verify that these great timings can be attributed to Couchbase:<\/p>\n<ul>\n<li>open a new tab in your browser and navigate to <a href=\"https:\/\/localhost:8091\"><code>https:\/\/localhost:8091<\/code><\/a>.<\/li>\n<li>connect to the web console.<\/li>\n<li>go to the <code>Data Buckets<\/code> tab and click on the <code>Documents<\/code> button for the bucket you elected to use (&#8220;default&#8221;).<\/li>\n<\/ul>\n<p>What you see in this screen (<a href=\"https:\/\/localhost:8091\/index.html#sec=documents&amp;viewsBucket=default\">quick link<\/a> for the lazies) should be similar to this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-10261 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2015\/12\/cacheddocs.png\" alt=\"Spring Cache documents in Couchbase console\" width=\"789\" height=\"545\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2015\/12\/cacheddocs.png 789w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2015\/12\/cacheddocs-300x207.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2015\/12\/cacheddocs-768x530.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2015\/12\/cacheddocs-20x14.png 20w\" sizes=\"auto, (max-width: 789px) 100vw, 789px\" \/><\/p>\n<p>We can see that both books were cached in couchbase, using the <strong><code>cache:CACHE_NAME:CACHE_KEY<\/code><\/strong> pattern for the document IDs.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>Easy caching using Couchbase is now at your fingertips!<\/p>\n<p>There is much more that <code>Spring Cache<\/code> can do for you (for instance, choosing how to create the cache key, conditional caching, cache eviction, etc&#8230;), and there are specificities to <code>couchbase-spring-cache<\/code> (eg. for cache clearing you can choose between using a view that will only remove relevant document or, if your bucket is dedicated to a single cache, use the <code>flush<\/code> mechanism&#8230;).<\/p>\n<p>I hope this introductory tutorial whetted your appetite for easy caching using <code>Spring Cache<\/code> and <code>Couchbase<\/code>!<\/p>\n<p>The next steps will probably be to introduce alternative storage formats (like JSON) and to offer the artifact on Maven Central or a similar publicly accessible Maven repository (<a href=\"https:\/\/bintray.com\">Bintray<\/a> anyone?)&#8230;<\/p>\n<p>Watch out for Spring-related news in the near future!<\/p>\n<p>In the meantime, happy coding :)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post, we&#8217;ll discover how to cache data easily using Spring Cache and Couchbase as a backing store manager. Table of Contents A Word Of Introduction The Cache Abstraction The Couchbase Implementation Getting couchbase-spring-cache and Putting it to [&hellip;]<\/p>\n","protected":false},"author":48,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1818],"tags":[1511,1424,1465],"ppma_author":[9022],"class_list":["post-2039","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-cache","tag-spring","tag-spring-data"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Cache Data with Spring Cache and Couchbase as Backing Store<\/title>\n<meta name=\"description\" content=\"Find out how to cache data by utilizing Spring Cache and Couchbase as a backing store. Easy caching using Couchbase is now at your fingertips!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Backing Spring Cache With Couchbase\" \/>\n<meta property=\"og:description\" content=\"Find out how to cache data by utilizing Spring Cache and Couchbase as a backing store. Easy caching using Couchbase is now at your fingertips!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-12-16T19:37:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-12T08:12:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2015\/12\/cacheddocs.png\" \/>\n<meta name=\"author\" content=\"Simon Basle, Software Engineer, Pivotal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Simon Basle, Software Engineer, Pivotal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/\"},\"author\":{\"name\":\"Simon Basle, Software Engineer, Pivotal\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/a4086d75b59570cc2e5ff66d98c5d1a1\"},\"headline\":\"Backing Spring Cache With Couchbase\",\"datePublished\":\"2015-12-16T19:37:00+00:00\",\"dateModified\":\"2024-09-12T08:12:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/\"},\"wordCount\":1117,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"keywords\":[\"Cache\",\"spring\",\"spring-data\"],\"articleSection\":[\"Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/\",\"name\":\"Cache Data with Spring Cache and Couchbase as Backing Store\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-12-16T19:37:00+00:00\",\"dateModified\":\"2024-09-12T08:12:09+00:00\",\"description\":\"Find out how to cache data by utilizing Spring Cache and Couchbase as a backing store. Easy caching using Couchbase is now at your fingertips!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-spring-cache\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Backing Spring Cache With Couchbase\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/a4086d75b59570cc2e5ff66d98c5d1a1\",\"name\":\"Simon Basle, Software Engineer, Pivotal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g4b2bcd169f85f21cee7b8a0e0c9e7854\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g\",\"caption\":\"Simon Basle, Software Engineer, Pivotal\"},\"description\":\"Simon Basl_ is a Paris-based Software Engineer working in the Spring team at Pivotal. Previously, he worked in the Couchbase Java SDK team. His interests span software design aspects (OOP, design patterns, software architecture), rich clients, what lies beyond code (continuous integration, (D)VCS, best practices), and reactive programming. He is also an editor for the French version of InfoQ.com.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/author\\\/simon-basle\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Cache Data with Spring Cache and Couchbase as Backing Store","description":"Find out how to cache data by utilizing Spring Cache and Couchbase as a backing store. Easy caching using Couchbase is now at your fingertips!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/","og_locale":"en_US","og_type":"article","og_title":"Backing Spring Cache With Couchbase","og_description":"Find out how to cache data by utilizing Spring Cache and Couchbase as a backing store. Easy caching using Couchbase is now at your fingertips!","og_url":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/","og_site_name":"The Couchbase Blog","article_published_time":"2015-12-16T19:37:00+00:00","article_modified_time":"2024-09-12T08:12:09+00:00","og_image":[{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2015\/12\/cacheddocs.png","type":"","width":"","height":""}],"author":"Simon Basle, Software Engineer, Pivotal","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Simon Basle, Software Engineer, Pivotal","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/"},"author":{"name":"Simon Basle, Software Engineer, Pivotal","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/a4086d75b59570cc2e5ff66d98c5d1a1"},"headline":"Backing Spring Cache With Couchbase","datePublished":"2015-12-16T19:37:00+00:00","dateModified":"2024-09-12T08:12:09+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/"},"wordCount":1117,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["Cache","spring","spring-data"],"articleSection":["Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/","url":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/","name":"Cache Data with Spring Cache and Couchbase as Backing Store","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2015-12-16T19:37:00+00:00","dateModified":"2024-09-12T08:12:09+00:00","description":"Find out how to cache data by utilizing Spring Cache and Couchbase as a backing store. Easy caching using Couchbase is now at your fingertips!","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-spring-cache\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Backing Spring Cache With Couchbase"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/a4086d75b59570cc2e5ff66d98c5d1a1","name":"Simon Basle, Software Engineer, Pivotal","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g4b2bcd169f85f21cee7b8a0e0c9e7854","url":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g","caption":"Simon Basle, Software Engineer, Pivotal"},"description":"Simon Basl_ is a Paris-based Software Engineer working in the Spring team at Pivotal. Previously, he worked in the Couchbase Java SDK team. His interests span software design aspects (OOP, design patterns, software architecture), rich clients, what lies beyond code (continuous integration, (D)VCS, best practices), and reactive programming. He is also an editor for the French version of InfoQ.com.","url":"https:\/\/www.couchbase.com\/blog\/author\/simon-basle\/"}]}},"acf":[],"authors":[{"term_id":9022,"user_id":48,"is_guest":0,"slug":"simon-basle","display_name":"Simon Basle, Software Engineer, Pivotal","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2039","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/48"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=2039"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2039\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=2039"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=2039"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=2039"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=2039"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}