{"id":81599,"date":"2018-09-10T13:00:34","date_gmt":"2018-09-10T10:00:34","guid":{"rendered":"https:\/\/www.javacodegeeks.com\/?p=81599"},"modified":"2018-09-10T01:11:05","modified_gmt":"2018-09-09T22:11:05","slug":"spring-data-cassandra-application","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html","title":{"rendered":"Containerising a Spring Data Cassandra application"},"content":{"rendered":"<p>I\u2019m continuing my journey of learning Docker. I am still keeping it simple at this point. This time around, I am going to tackle converting a Spring and Cassandra application to use containers instead of running locally on the host machine. More precisely, using Spring Data Cassandra to sort out the application.<\/p>\n<p>I wish I looked at doing this change a while ago. I have written a fair amount of posts on Cassandra and each time I had to <code>cd<\/code> to the correct directory or have a shortcut to start it up. I guess it\u2019s not that big of a deal, but there were a few other things involved. Such as, dropping and recreating keyspaces so I could test my application from scratch. Now, I just delete the container and restart it. To me anyway, this is helpful!<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/09\/docker-hong-kong-21.png\"><img decoding=\"async\" class=\"aligncenter wp-image-81611\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/09\/docker-hong-kong-21.png\" alt=\"cassandra\" width=\"820\" height=\"546\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/09\/docker-hong-kong-21.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/09\/docker-hong-kong-21-300x200.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/09\/docker-hong-kong-21-768x512.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><\/p>\n<p>This post will be slightly different from my previous post, <a href=\"https:\/\/www.javacodegeeks.com\/2018\/09\/docker-existing-application-containers.html\" target=\"_blank\" rel=\"noopener\">Using Docker to shove an existing application into containers<\/a>. Instead, I will focus slightly more on the application side and remove the intermediate steps of using only Docker and instead will jump straight into Docker Compose.<\/p>\n<h3>Containers, containers, containers<\/h3>\n<p>I think it\u2019s best to start on the container side of the project since the application depends on the configuration of the Cassandra container.<\/p>\n<p>Let\u2019s go!<\/p>\n<pre class=\"brush:java; wrap-lines:false\">FROM openjdk:10-jre-slim\r\nLABEL maintainer=\"Dan Newton\"\r\nARG JAR_FILE\r\nADD target\/${JAR_FILE} app.jar\r\nENTRYPOINT [\"java\", \"-jar\", \"\/app.jar\"]<\/pre>\n<p>There\u2019s not much going on here. This <code>Dockerfile<\/code> builds the Spring application image that will be put into a container in a few moments.<\/p>\n<p>Next up is the <code>docker-compose<\/code> file. This is will build both the Spring application and Cassandra containers:<\/p>\n<pre class=\"brush:java; wrap-lines:false\">version: '3'\r\nservices:\r\n  app:\r\n    build:\r\n      context: .\r\n      args:\r\n        JAR_FILE: \/spring-data-cassandra-docker-1.0.0.jar\r\n    restart: always\r\n  cassandra:\r\nimage: \"cassandra\"<\/pre>\n<p>Again, there isn\u2019t too much here. The <code>app<\/code> container builds the Spring application using the <code>Dockerfile<\/code> defined previously. The <code>cassandra<\/code> container instead relies on an existing image, appropriately named <code>cassandra<\/code>.<\/p>\n<p>One thing that stands out is that the <code>restart<\/code> property is set to <code>always<\/code>. This was my lazy attempt to get past how long Cassandra takes to start and the fact that all the containers started with <code>docker-compose<\/code> start at the same time. This lead to a situation where the application is trying to connect to Cassandra without it being ready. Unfortunately, this leads to the application dying. I hoped that it would have some retry capability for initial connectivity built in\u2026 But it does not.<\/p>\n<p>When we go through the code, we will see how to deal with the initial Cassandra connection programmatically instead of relying on the application dying and restarting multiple times. You will see my version of handling the connection anyway\u2026 I\u2019m not really a fan of my solution but everything else I tried caused me much more pain.<\/p>\n<h3>A dash of code<\/h3>\n<p>I said this post would focus more on the application code, which it will, but we are not going to dive into everything I put within this application and how to use Cassandra. For that sort of information, you can have a look at my older posts, which I\u2019ll link at the end. What we will do though, is examine the configuration code that creates the beans that connect to Cassandra.<\/p>\n<p>First, let\u2019s go through <code>ClusterConfig<\/code> which sets up the Cassandra cluster:<\/p>\n<pre class=\"brush:java; wrap-lines:false\">@Configuration\r\npublic class ClusterConfig extends AbstractClusterConfiguration {\r\n\r\n  private final String keyspace;\r\n  private final String hosts;\r\n\r\n  ClusterConfig(\r\n      @Value(\"${spring.data.cassandra.keyspace-name}\") String keyspace,\r\n      @Value(\"${spring.data.cassandra.contact-points}\") String hosts) {\r\n    this.keyspace = keyspace;\r\n    this.hosts = hosts;\r\n  }\r\n\r\n  @Bean\r\n  @Override\r\n  public CassandraClusterFactoryBean cluster() {\r\n\r\n    RetryingCassandraClusterFactoryBean bean = new RetryingCassandraClusterFactoryBean();\r\n\r\n    bean.setAddressTranslator(getAddressTranslator());\r\n    bean.setAuthProvider(getAuthProvider());\r\n    bean.setClusterBuilderConfigurer(getClusterBuilderConfigurer());\r\n    bean.setClusterName(getClusterName());\r\n    bean.setCompressionType(getCompressionType());\r\n    bean.setContactPoints(getContactPoints());\r\n    bean.setLoadBalancingPolicy(getLoadBalancingPolicy());\r\n    bean.setMaxSchemaAgreementWaitSeconds(getMaxSchemaAgreementWaitSeconds());\r\n    bean.setMetricsEnabled(getMetricsEnabled());\r\n    bean.setNettyOptions(getNettyOptions());\r\n    bean.setPoolingOptions(getPoolingOptions());\r\n    bean.setPort(getPort());\r\n    bean.setProtocolVersion(getProtocolVersion());\r\n    bean.setQueryOptions(getQueryOptions());\r\n    bean.setReconnectionPolicy(getReconnectionPolicy());\r\n    bean.setRetryPolicy(getRetryPolicy());\r\n    bean.setSpeculativeExecutionPolicy(getSpeculativeExecutionPolicy());\r\n    bean.setSocketOptions(getSocketOptions());\r\n    bean.setTimestampGenerator(getTimestampGenerator());\r\n\r\n    bean.setKeyspaceCreations(getKeyspaceCreations());\r\n    bean.setKeyspaceDrops(getKeyspaceDrops());\r\n    bean.setStartupScripts(getStartupScripts());\r\n    bean.setShutdownScripts(getShutdownScripts());\r\n\r\n    return bean;\r\n  }\r\n\r\n  @Override\r\n  protected List getKeyspaceCreations() {\r\n    final CreateKeyspaceSpecification specification =\r\n        CreateKeyspaceSpecification.createKeyspace(keyspace)\r\n            .ifNotExists()\r\n            .with(KeyspaceOption.DURABLE_WRITES, true)\r\n            .withSimpleReplication();\r\n    return List.of(specification);\r\n  }\r\n\r\n  @Override\r\n  protected String getContactPoints() {\r\n    return hosts;\r\n  }\r\n}<\/pre>\n<p>There isn\u2019t too much there, but there would be even less if Spring would retry the initial connection to Cassandra. Anyway, let\u2019s leave that part for a few minutes and focus on the other points in this class.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>The original reason I created <code>ClusterConfig<\/code> was to create the keyspace that the application will use. To do this <code>getKeyspaceCreations<\/code> was overridden. When the application connects it will execute the query defined in this method to create the keyspace.<\/p>\n<p>If this wasn\u2019t needed and the keyspace was created in some other way, for example, a script executed as part of creating the Cassandra container, Spring Boot\u2019s auto-configuration could be relied upon instead. This actually allows the whole application to be configured by the properties defined in <code>application.properties<\/code> and nothing else. Alas, it was not meant to be.<\/p>\n<p>Since we have defined an <code>AbstractClusterConfiguration<\/code>, Spring Boot will disable its configuration in this area. Therefore, we need to define the <code>contactPoints<\/code> (I named the variable <code>hosts<\/code>) manually by overriding the <code>getContactPoints<\/code> method. Originally this was only defined in <code>application.properties<\/code>. I realised I needed to make this change once I started getting the following error:<\/p>\n<pre class=\"brush:java wrap-lines:false\">All host(s) tried for query failed (tried: localhost\/127.0.0.1:9042 (com.datastax.driver.core.exceptions.TransportException: [localhost\/127.0.0.1:9042] Cannot connect))<\/pre>\n<p>Before I created <code>ClusterConfig<\/code> the address was <code>cassandra<\/code> rather than <code>localhost<\/code>.<\/p>\n<p>No other properties for the cluster need to be configured as Spring\u2019s defaults are good enough for this scenario.<\/p>\n<p>I have mentioned <code>application.properties<\/code> so much at this point, I should probably show you what is in it.<\/p>\n<pre class=\"brush:java wrap-lines:false\">spring.data.cassandra.keyspace-name=mykeyspace\r\nspring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS\r\nspring.data.cassandra.contact-points=cassandra<\/pre>\n<p><code>keyspace-name<\/code> and <code>contact-points<\/code> have already popped up since they are related to configuring the cluster. <code>schema-action<\/code> is needed to create tables based on the entities in the project. We don\u2019t need to do anything else here as auto-configuration is still working in this area.<\/p>\n<p>The fact that the <code>contact-points<\/code> value is set to <code>cassandra<\/code> is very important. This domain name originates from the name given to the container, in this case, <code>cassandra<\/code>. Therefore either <code>cassandra<\/code> can be used or the actual IP of the container. The domain name is definitely easier since it will always be static between deployments. Just to test this theory out, you can change the name of the <code>cassandra<\/code> container to whatever you want and it will still connect, as long as you change it in the <code>application.properties<\/code> as well.<\/p>\n<p>Back to the <code>ClusterConfig<\/code> code. More precisely, the <code>cluster<\/code> bean. I have pasted the code below again so it\u2019s easier to look at:<\/p>\n<pre class=\"brush:xml; wrap-lines:false\">@Configuration\r\npublic class ClusterConfig extends AbstractClusterConfiguration {\r\n\r\n  \/\/ other stuff\r\n\r\n  @Bean\r\n  @Override\r\n  public CassandraClusterFactoryBean cluster() {\r\n\r\n    RetryingCassandraClusterFactoryBean bean = new RetryingCassandraClusterFactoryBean();\r\n\r\n    bean.setAddressTranslator(getAddressTranslator());\r\n    bean.setAuthProvider(getAuthProvider());\r\n    bean.setClusterBuilderConfigurer(getClusterBuilderConfigurer());\r\n    bean.setClusterName(getClusterName());\r\n    bean.setCompressionType(getCompressionType());\r\n    bean.setContactPoints(getContactPoints());\r\n    bean.setLoadBalancingPolicy(getLoadBalancingPolicy());\r\n    bean.setMaxSchemaAgreementWaitSeconds(getMaxSchemaAgreementWaitSeconds());\r\n    bean.setMetricsEnabled(getMetricsEnabled());\r\n    bean.setNettyOptions(getNettyOptions());\r\n    bean.setPoolingOptions(getPoolingOptions());\r\n    bean.setPort(getPort());\r\n    bean.setProtocolVersion(getProtocolVersion());\r\n    bean.setQueryOptions(getQueryOptions());\r\n    bean.setReconnectionPolicy(getReconnectionPolicy());\r\n    bean.setRetryPolicy(getRetryPolicy());\r\n    bean.setSpeculativeExecutionPolicy(getSpeculativeExecutionPolicy());\r\n    bean.setSocketOptions(getSocketOptions());\r\n    bean.setTimestampGenerator(getTimestampGenerator());\r\n\r\n    bean.setKeyspaceCreations(getKeyspaceCreations());\r\n    bean.setKeyspaceDrops(getKeyspaceDrops());\r\n    bean.setStartupScripts(getStartupScripts());\r\n    bean.setShutdownScripts(getShutdownScripts());\r\n\r\n    return bean;\r\n  }\r\n\r\n  \/\/ other stuff\r\n}<\/pre>\n<p>This code is only needed to allow retries on the initial Cassandra connection. It is annoying, but I could not come up with another simple solution. If you have a nicer one then please let me know!<\/p>\n<p>What I have done is actually quite simple, but the code itself is not very nice. The <code>cluster<\/code> method is a carbon copy of the overridden version from <code>AbstractClusterConfiguration<\/code>, with the exception of the <code>RetryingCassandraClusterFactoryBean<\/code> (my own class). The original function used a <code>CassandraClusterFactoryBean<\/code> (Spring class) instead.<\/p>\n<p>Below is the <code>RetryingCassandraClusterFactoryBean<\/code>:<\/p>\n<pre class=\"brush:xml; wrap-lines:false\">public class RetryingCassandraClusterFactoryBean extends CassandraClusterFactoryBean {\r\n\r\n  private static final Logger LOG =\r\n      LoggerFactory.getLogger(RetryingCassandraClusterFactoryBean.class);\r\n\r\n  @Override\r\n  public void afterPropertiesSet() throws Exception {\r\n    connect();\r\n  }\r\n\r\n  private void connect() throws Exception {\r\n    try {\r\n      super.afterPropertiesSet();\r\n    } catch (TransportException | IllegalArgumentException | NoHostAvailableException e) {\r\n      LOG.warn(e.getMessage());\r\n      LOG.warn(\"Retrying connection in 10 seconds\");\r\n      sleep();\r\n      connect();\r\n    }\r\n  }\r\n\r\n  private void sleep() {\r\n    try {\r\n      Thread.sleep(10000);\r\n    } catch (InterruptedException ignored) {\r\n    }\r\n  }\r\n}<\/pre>\n<p>The <code>afterPropertiesSet<\/code> method in the original <code>CassandraClusterFactoryBean<\/code> takes its values and creates the representation of a Cassandra cluster by finally delegating to the Datastax Java driver. As I have mentioned throughout the post. If it fails to establish a connection, an exception will be thrown and if not caught will cause the application to terminate. That is the whole point of the above code. It wraps the <code>afterPropertiesSet<\/code> in a try-catch block specified for the exceptions that can be thrown.<\/p>\n<p>The <code>sleep<\/code> is added to give Cassandra some time to actually start up. There is no point trying to reconnect straight away when the previous attempt failed.<\/p>\n<p>Using this code the application will eventually connect to Cassandra.<\/p>\n<p>At this point, I would normally show you some meaningless logs to prove that the application works, but in this situation, it really does not bring anything to the table. Just trust me when I say, if you run the below command:<\/p>\n<pre class=\"brush:bash\">mvn clean install &amp;&amp; docker-compose up<\/pre>\n<p>Then the Spring application image is created and both containers are spun up.<\/p>\n<h3>Conclusion<\/h3>\n<p>We have had a look at how to put a Spring application that connects to a Cassandra database into containers. One for the application and another for Cassandra. The application image is built from the project\u2019s code, whereas the Cassandra image is taken from Docker Hub. The image name is <code>cassandra<\/code> just to make sure no one forgets. In general connecting the two containers together was relatively simple but the application needed some adjustments to allow retries when connecting to Cassandra running in the other container. This made the code a bit uglier, but it works at least\u2026 Thanks to the code written in this post, I now have another application that I don\u2019t need to set up on my own machine.<\/p>\n<p>The code used in this post can be found on my <a href=\"https:\/\/github.com\/lankydan\/spring-data-cassandra-docker\" target=\"_blank\" rel=\"noopener\">GitHub<\/a>.<\/p>\n<p>If you found this post helpful, you can follow me on Twitter at <a href=\"http:\/\/www.twitter.com\/LankyDanDev\" target=\"_blank\" rel=\"noopener\">@LankyDanDev<\/a> to keep up with my new posts.<\/p>\n<h3>Links to my Spring Data Cassandra posts<\/h3>\n<ul>\n<li><a href=\"https:\/\/lankydanblog.com\/2017\/10\/12\/getting-started-with-spring-data-cassandra\/\" target=\"_blank\" rel=\"noopener\">Getting started with Spring Data Cassandra<\/a><\/li>\n<li><a href=\"https:\/\/lankydanblog.com\/2017\/10\/22\/separate-keyspaces-with-spring-data-cassandra\/\" target=\"_blank\" rel=\"noopener\">Separate keyspaces with Spring Data Cassandra<\/a><\/li>\n<li><a href=\"https:\/\/lankydanblog.com\/2017\/11\/12\/multiple-keyspaces-using-a-single-spring-data-cassandratemplate\/\" target=\"_blank\" rel=\"noopener\">Multiple keyspaces using a single Spring Data CassandraTemplate<\/a><\/li>\n<li><a href=\"https:\/\/lankydanblog.com\/2017\/11\/26\/more-complex-modelling-with-spring-data-cassandra\/\" target=\"_blank\" rel=\"noopener\">More complex modelling with Spring Data Cassandra<\/a><\/li>\n<li><a href=\"https:\/\/lankydanblog.com\/2017\/12\/03\/startup-and-shutdown-scripts-in-spring-data-cassandra\/\" target=\"_blank\" rel=\"noopener\">Startup and shutdown scripts in Spring Data Cassandra<\/a><\/li>\n<li><a href=\"https:\/\/lankydanblog.com\/2017\/12\/11\/reactive-streams-with-spring-data-cassandra\/\" target=\"_blank\" rel=\"noopener\">Reactive Streams with Spring Data Cassandra<\/a><\/li>\n<li><a href=\"https:\/\/lankydanblog.com\/2017\/12\/16\/plumbing-included-with-auto-configuration-in-spring-data-cassandra\/\" target=\"_blank\" rel=\"noopener\">Plumbing included with auto-configuration in Spring Data Cassandra<\/a><\/li>\n<li><a href=\"https:\/\/lankydanblog.com\/2018\/04\/15\/interacting-with-cassandra-using-the-datastax-java-driver\/\" target=\"_blank\" rel=\"noopener\">Interacting with Cassandra using the Datastax Java driver<\/a><\/li>\n<\/ul>\n<p>Wow, I didn\u2019t realise I wrote so many Cassandra posts.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td>Published on Java Code Geeks with permission by Dan Newton, partner at our <a href=\"\/\/www.javacodegeeks.com\/join-us\/jcg\/\" target=\"_blank\" rel=\"noopener\">JCG program<\/a>. See the original article here: <a href=\"https:\/\/lankydanblog.com\/2018\/09\/08\/containerising-a-spring-data-cassandra-application\/\" target=\"_blank\" rel=\"noopener\">Containerising a Spring Data Cassandra application<\/a><\/p>\n<p>Opinions expressed by Java Code Geeks contributors are their own.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>I\u2019m continuing my journey of learning Docker. I am still keeping it simple at this point. This time around, I am going to tackle converting a Spring and Cassandra application to use containers instead of running locally on the host machine. More precisely, using Spring Data Cassandra to sort out the application. I wish I &hellip;<\/p>\n","protected":false},"author":12894,"featured_media":53,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[834,936,30,854,321,1636],"class_list":["post-81599","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-cassandra","tag-docker","tag-spring","tag-spring-boot","tag-spring-data","tag-spring-data-cassandra"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Containerising a Spring Data Cassandra application - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn more about Cassandra? Check out our article where we are containerising a spring data cassandra application!\" \/>\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.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Containerising a Spring Data Cassandra application - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn more about Cassandra? Check out our article where we are containerising a spring data cassandra application!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2018-09-10T10:00:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-cassandra-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Dan Newton\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@LankyDanDev\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Dan Newton\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html\"},\"author\":{\"name\":\"Dan Newton\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/00ad664c44d777ebfa4d984dcf2717e2\"},\"headline\":\"Containerising a Spring Data Cassandra application\",\"datePublished\":\"2018-09-10T10:00:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html\"},\"wordCount\":1415,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-cassandra-logo.jpg\",\"keywords\":[\"Cassandra\",\"Docker\",\"Spring\",\"Spring Boot\",\"Spring Data\",\"SPRING DATA CASSANDRA\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html\",\"name\":\"Containerising a Spring Data Cassandra application - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-cassandra-logo.jpg\",\"datePublished\":\"2018-09-10T10:00:34+00:00\",\"description\":\"Interested to learn more about Cassandra? Check out our article where we are containerising a spring data cassandra application!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-cassandra-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-cassandra-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/spring-data-cassandra-application.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Containerising a Spring Data Cassandra application\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/00ad664c44d777ebfa4d984dcf2717e2\",\"name\":\"Dan Newton\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b5024a6405bf07e14dacc299779fc0abded33b42a05190784776429e2c76435f?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b5024a6405bf07e14dacc299779fc0abded33b42a05190784776429e2c76435f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b5024a6405bf07e14dacc299779fc0abded33b42a05190784776429e2c76435f?s=96&d=mm&r=g\",\"caption\":\"Dan Newton\"},\"sameAs\":[\"https:\\\/\\\/lankydanblog.com\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/danknewton\\\/\",\"https:\\\/\\\/x.com\\\/LankyDanDev\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/dan-newton\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Containerising a Spring Data Cassandra application - Java Code Geeks","description":"Interested to learn more about Cassandra? Check out our article where we are containerising a spring data cassandra application!","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.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html","og_locale":"en_US","og_type":"article","og_title":"Containerising a Spring Data Cassandra application - Java Code Geeks","og_description":"Interested to learn more about Cassandra? Check out our article where we are containerising a spring data cassandra application!","og_url":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2018-09-10T10:00:34+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-cassandra-logo.jpg","type":"image\/jpeg"}],"author":"Dan Newton","twitter_card":"summary_large_image","twitter_creator":"@LankyDanDev","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Dan Newton","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html"},"author":{"name":"Dan Newton","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/00ad664c44d777ebfa4d984dcf2717e2"},"headline":"Containerising a Spring Data Cassandra application","datePublished":"2018-09-10T10:00:34+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html"},"wordCount":1415,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-cassandra-logo.jpg","keywords":["Cassandra","Docker","Spring","Spring Boot","Spring Data","SPRING DATA CASSANDRA"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html","url":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html","name":"Containerising a Spring Data Cassandra application - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-cassandra-logo.jpg","datePublished":"2018-09-10T10:00:34+00:00","description":"Interested to learn more about Cassandra? Check out our article where we are containerising a spring data cassandra application!","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-cassandra-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-cassandra-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/spring-data-cassandra-application.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Containerising a Spring Data Cassandra application"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/00ad664c44d777ebfa4d984dcf2717e2","name":"Dan Newton","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b5024a6405bf07e14dacc299779fc0abded33b42a05190784776429e2c76435f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b5024a6405bf07e14dacc299779fc0abded33b42a05190784776429e2c76435f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b5024a6405bf07e14dacc299779fc0abded33b42a05190784776429e2c76435f?s=96&d=mm&r=g","caption":"Dan Newton"},"sameAs":["https:\/\/lankydanblog.com\/","https:\/\/www.linkedin.com\/in\/danknewton\/","https:\/\/x.com\/LankyDanDev"],"url":"https:\/\/www.javacodegeeks.com\/author\/dan-newton"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/81599","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/12894"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=81599"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/81599\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/53"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=81599"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=81599"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=81599"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}