diff --git a/persistence-modules/java-cockroachdb/README.md b/persistence-modules/java-cockroachdb/README.md
new file mode 100644
index 0000000000..0f0381212d
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Guide to CockroachDB in Java](http://www.baeldung.com/)
diff --git a/persistence-modules/java-cockroachdb/pom.xml b/persistence-modules/java-cockroachdb/pom.xml
new file mode 100644
index 0000000000..2b6f9651bc
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/pom.xml
@@ -0,0 +1,74 @@
+
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+ ../../
+
+
+ 4.0.0
+
+ com.baeldung
+ java-cockroachdb
+ 1.0-SNAPSHOT
+
+
+ 42.1.4
+
+
+
+
+ org.postgresql
+ postgresql
+ ${postgresql.version}
+
+
+
+
+
+ integration
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ integration-test
+
+ test
+
+
+
+ **/*ManualTest.java
+
+
+ **/*IntegrationTest.java
+
+
+
+
+
+
+ json
+
+
+
+
+
+
+
+
+
+
+ Central
+ Central
+ http://repo1.maven.org/maven2/
+ default
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/domain/Article.java b/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/domain/Article.java
new file mode 100644
index 0000000000..dcc9dfb5b7
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/domain/Article.java
@@ -0,0 +1,43 @@
+package com.baeldung.cockroachdb.domain;
+
+import java.util.UUID;
+
+public class Article {
+
+ private UUID id;
+
+ private String title;
+
+ private String author;
+
+ public Article(UUID id, String title, String author) {
+ this.id = id;
+ this.title = title;
+ this.author = author;
+ }
+
+ public UUID getId() {
+ return id;
+ }
+
+ public void setId(UUID id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+}
diff --git a/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/repository/ArticleRepository.java b/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/repository/ArticleRepository.java
new file mode 100644
index 0000000000..a37c19e397
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/repository/ArticleRepository.java
@@ -0,0 +1,172 @@
+package com.baeldung.cockroachdb.repository;
+
+import com.baeldung.cockroachdb.domain.Article;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Repository for the articles table related operations
+ */
+public class ArticleRepository {
+
+ private static final String TABLE_NAME = "articles";
+ private Connection connection;
+
+ public ArticleRepository(Connection connection) {
+ this.connection = connection;
+ }
+
+ /**
+ * Creates the articles table.
+ */
+ public void createTable() throws SQLException {
+ StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS ").append(TABLE_NAME)
+ .append("(id uuid PRIMARY KEY, ")
+ .append("title string,")
+ .append("author string)");
+
+ final String query = sb.toString();
+ Statement stmt = connection.createStatement();
+ stmt.execute(query);
+ }
+
+ /**
+ * Alter the articles table adding a column
+ *
+ * @param columnName Column name of the additional column
+ * @param columnType Column type of the additional column
+ * @throws SQLException
+ */
+ public void alterTable(String columnName, String columnType) throws SQLException {
+ StringBuilder sb = new StringBuilder("ALTER TABLE ").append(TABLE_NAME)
+ .append(" ADD ")
+ .append(columnName)
+ .append(" ")
+ .append(columnType);
+
+ final String query = sb.toString();
+ Statement stmt = connection.createStatement();
+ stmt.execute(query);
+ }
+
+ /**
+ * Insert a new article in the articles table
+ *
+ * @param article New article to insert
+ * @throws SQLException
+ */
+ public void insertArticle(Article article) throws SQLException {
+ StringBuilder sb = new StringBuilder("INSERT INTO ").append(TABLE_NAME)
+ .append("(id, title, author) ")
+ .append("VALUES (?,?,?)");
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, article.getId().toString());
+ preparedStatement.setString(2, article.getTitle());
+ preparedStatement.setString(3, article.getAuthor());
+ preparedStatement.execute();
+ }
+
+ /**
+ * Select article by Title
+ *
+ * @param title title of the article to retrieve
+ * @return article with the given title
+ * @throws SQLException
+ */
+ public Article selectByTitle(String title) throws SQLException {
+ StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME)
+ .append(" WHERE title = ?");
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, title);
+
+ try (ResultSet rs = preparedStatement.executeQuery()) {
+
+ List articles = new ArrayList<>();
+
+ while (rs.next()) {
+ Article article = new Article(
+ UUID.fromString(rs.getString("id")),
+ rs.getString("title"),
+ rs.getString("author")
+ );
+ articles.add(article);
+ }
+ return articles.get(0);
+ }
+
+ }
+
+ /**
+ * Select all the articles
+ *
+ * @return list of all articles
+ * @throws SQLException
+ */
+ public List selectAll() throws SQLException {
+ StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME);
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ try (ResultSet rs = preparedStatement.executeQuery()) {
+
+ List articles = new ArrayList<>();
+
+ while (rs.next()) {
+ Article article = new Article(
+ UUID.fromString(rs.getString("id")),
+ rs.getString("title"),
+ rs.getString("author")
+ );
+ articles.add(article);
+ }
+ return articles;
+ }
+ }
+
+ /**
+ * Delete article by title
+ *
+ * @param title title of the article to delete
+ * @throws SQLException
+ */
+ public void deleteArticleByTitle(String title) throws SQLException {
+ StringBuilder sb = new StringBuilder("DELETE FROM ").append(TABLE_NAME)
+ .append(" WHERE title = ?");
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, title);
+ preparedStatement.execute();
+ }
+
+ /**
+ * Delete all rows in the table
+ *
+ * @throws SQLException
+ */
+ public void truncateTable() throws SQLException {
+ StringBuilder sb = new StringBuilder("TRUNCATE TABLE ").append(TABLE_NAME);
+
+ final String query = sb.toString();
+ Statement stmt = connection.createStatement();
+ stmt.execute(query);
+ }
+
+ /**
+ * Delete table
+ */
+ public void deleteTable() throws SQLException {
+ StringBuilder sb = new StringBuilder("DROP TABLE IF EXISTS ").append(TABLE_NAME);
+
+ final String query = sb.toString();
+ Statement stmt = connection.createStatement();
+ stmt.execute(query);
+ }
+}
diff --git a/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java
new file mode 100644
index 0000000000..9eb00b3651
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java
@@ -0,0 +1,208 @@
+package com.baeldung.cockroachdb;
+
+import com.baeldung.cockroachdb.domain.Article;
+import com.baeldung.cockroachdb.repository.ArticleRepository;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.postgresql.util.PSQLException;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ArticleRepositoryIntegrationTest {
+
+ private static final String TABLE_NAME = "articles";
+
+ private Connection con;
+ private ArticleRepository articleRepository;
+
+ @Before
+ public void connect() throws Exception {
+ Class.forName("org.postgresql.Driver");
+ con = DriverManager.getConnection("jdbc:postgresql://localhost:26257/testdb", "user17", "qwerty");
+
+ articleRepository = new ArticleRepository(con);
+ }
+
+ @Test
+ public void whenCreatingTable_thenCreatedCorrectly() throws Exception {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ PreparedStatement preparedStatement = con.prepareStatement("SHOW TABLES");
+ ResultSet resultSet = preparedStatement.executeQuery();
+ List tables = new ArrayList<>();
+ while (resultSet.next()) {
+ tables.add(resultSet.getString("Table"));
+ }
+
+ assertTrue(tables.stream().anyMatch(t -> t.equals(TABLE_NAME)));
+ }
+
+ @Test
+ public void whenAlteringTheTable_thenColumnAddedCorrectly() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ String columnName = "creationdate";
+ articleRepository.alterTable(columnName, "DATE");
+
+ String query = "SHOW COLUMNS FROM " + TABLE_NAME;
+ PreparedStatement preparedStatement = con.prepareStatement(query);
+ ResultSet resultSet = preparedStatement.executeQuery();
+ List columns = new ArrayList<>();
+ while (resultSet.next()) {
+ columns.add(resultSet.getString("Field"));
+ }
+
+ assertTrue(columns.stream().anyMatch(c -> c.equals(columnName)));
+ }
+
+ @Test
+ public void whenInsertingNewArticle_thenArticleExists() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ String title = "Guide to CockroachDB in Java";
+ String author = "baeldung";
+ Article article = new Article(UUID.randomUUID(), title, author);
+ articleRepository.insertArticle(article);
+
+ Article savedArticle = articleRepository.selectByTitle(title);
+ assertEquals(article.getTitle(), savedArticle.getTitle());
+ }
+
+ @Test
+ public void whenSelectingAllArticles_thenAllArticlesAreReturned() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ List savedArticles = articleRepository.selectAll();
+
+ assertEquals(2, savedArticles.size());
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("Guide to CockroachDB in Java")));
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("A Guide to MongoDB with Java")));
+ }
+
+ @Test
+ public void whenDeletingArticleByTtile_thenArticleIsDeleted() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ articleRepository.deleteArticleByTitle("A Guide to MongoDB with Java");
+
+ List savedArticles = articleRepository.selectAll();
+ assertEquals(1, savedArticles.size());
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("Guide to CockroachDB in Java")));
+ assertFalse(savedArticles.stream().anyMatch(a -> a.getTitle().equals("A Guide to MongoDB with Java")));
+ }
+
+ @Test(expected = PSQLException.class)
+ public void whenDeletingATable_thenExceptionIfAccessed() throws SQLException {
+ articleRepository.createTable();
+ articleRepository.deleteTable();
+
+ StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME);
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = con.prepareStatement(query);
+ preparedStatement.executeQuery();
+ }
+
+ @Test
+ public void whenTruncatingATable_thenEmptyTable() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ articleRepository.truncateTable();
+
+ List savedArticles = articleRepository.selectAll();
+ assertEquals(0, savedArticles.size());
+ }
+
+ @Test
+ public void whenInsertingTwoArticlesWithSamePrimaryKeyInASingleTransaction_thenRollback() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ try {
+ con.setAutoCommit(false);
+
+ UUID articleId = UUID.randomUUID();
+
+ Article article = new Article(articleId, "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(articleId, "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ con.commit();
+ } catch (Exception e) {
+ con.rollback();
+ } finally {
+ con.setAutoCommit(true);
+ }
+
+ List savedArticles = articleRepository.selectAll();
+ assertEquals(0, savedArticles.size());
+ }
+
+ @Test
+ public void whenInsertingTwoArticlesInASingleTransaction_thenInserted() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ try {
+ con.setAutoCommit(false);
+
+ Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ con.commit();
+ } catch (Exception e) {
+ con.rollback();
+ } finally {
+ con.setAutoCommit(true);
+ }
+
+ List savedArticles = articleRepository.selectAll();
+ assertEquals(2, savedArticles.size());
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("Guide to CockroachDB in Java")));
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("A Guide to MongoDB with Java")));
+ }
+
+ @After
+ public void disconnect() throws SQLException {
+ articleRepository = null;
+ con.close();
+ con = null;
+ }
+}
diff --git a/pom.xml b/pom.xml
index 68edf19cb2..1050bb8ba2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -269,6 +269,7 @@
deeplearning4j
lucene
vraptor
+ persistence-modules/java-cockroachdb