diff --git a/pom.xml b/pom.xml
index eeaa0b9e93..8665dcb5a2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,7 @@
 		8.0.23
 		42.2.19
 		19.6.0.0
+		2.12.3
 
 		
 		4.0.3
diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml
index af9ad0904e..5de0c066bc 100644
--- a/spring-data-jdbc/pom.xml
+++ b/spring-data-jdbc/pom.xml
@@ -144,6 +144,20 @@
 			true
 		
 
+		
+			com.fasterxml.jackson.core
+			jackson-databind
+			${jackson.databind.version}
+			true
+		
+
+		
+			org.postgresql
+			postgresql
+			${postgresql.version}
+			true
+		
+
 		
 			org.hsqldb
 			hsqldb
@@ -172,13 +186,6 @@
 			test
 		
 
-		
-			org.postgresql
-			postgresql
-			${postgresql.version}
-			test
-		
-
 		
 			org.mariadb.jdbc
 			mariadb-java-client
diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/AbstractPostgresJsonReadingConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/AbstractPostgresJsonReadingConverter.java
new file mode 100644
index 0000000000..b7fe632c9c
--- /dev/null
+++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/AbstractPostgresJsonReadingConverter.java
@@ -0,0 +1,31 @@
+package org.springframework.data.jdbc.core.convert;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.postgresql.util.PGobject;
+import org.springframework.core.convert.converter.Converter;
+
+/**
+ * An abstract class for building your own converter for PostgerSQL's JSON[b].
+ *
+ * @author Nikita Konev
+ */
+public abstract class AbstractPostgresJsonReadingConverter implements Converter {
+    private final ObjectMapper objectMapper;
+    private final Class valueType;
+
+    public AbstractPostgresJsonReadingConverter(ObjectMapper objectMapper, Class valueType) {
+        this.objectMapper = objectMapper;
+        this.valueType = valueType;
+    }
+
+    @Override
+    public T convert(PGobject pgObject) {
+        try {
+            final String source = pgObject.getValue();
+            return objectMapper.readValue(source, valueType);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException("Unable to deserialize to json " + pgObject, e);
+        }
+    }
+}
diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/AbstractPostgresJsonWritingConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/AbstractPostgresJsonWritingConverter.java
new file mode 100644
index 0000000000..e380b790b1
--- /dev/null
+++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/AbstractPostgresJsonWritingConverter.java
@@ -0,0 +1,34 @@
+package org.springframework.data.jdbc.core.convert;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.postgresql.util.PGobject;
+import org.springframework.core.convert.converter.Converter;
+import java.sql.SQLException;
+
+/**
+ * An abstract class for building your own converter for PostgerSQL's JSON[b].
+ *
+ * @author Nikita Konev
+ */
+public abstract class AbstractPostgresJsonWritingConverter implements Converter {
+    private final ObjectMapper objectMapper;
+    private final boolean jsonb;
+
+    public AbstractPostgresJsonWritingConverter(ObjectMapper objectMapper, boolean jsonb) {
+        this.objectMapper = objectMapper;
+        this.jsonb = jsonb;
+    }
+
+    @Override
+    public PGobject convert(T source) {
+        try {
+            final PGobject pGobject = new PGobject();
+            pGobject.setType(jsonb ? "jsonb" : "json");
+            pGobject.setValue(objectMapper.writeValueAsString(source));
+            return pGobject;
+        } catch (JsonProcessingException | SQLException e) {
+            throw new RuntimeException("Unable to serialize to json " + source, e);
+        }
+    }
+}
diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/PostgresJsonConvertersIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/PostgresJsonConvertersIntegrationTests.java
new file mode 100644
index 0000000000..eaee709ae8
--- /dev/null
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/PostgresJsonConvertersIntegrationTests.java
@@ -0,0 +1,184 @@
+package org.springframework.data.jdbc.core.convert;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.*;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.convert.CustomConversions;
+import org.springframework.data.convert.ReadingConverter;
+import org.springframework.data.convert.WritingConverter;
+import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
+import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
+import org.springframework.data.jdbc.testing.TestConfiguration;
+import org.springframework.data.mapping.model.SimpleTypeHolder;
+import org.springframework.data.relational.core.dialect.Dialect;
+import org.springframework.data.relational.core.mapping.Table;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test for PostgreSQL JSON[B] converters.
+ * Start this test with -Dspring.profiles.active=postgres
+ *
+ * @author Nikita Konev
+ */
+@EnabledIfSystemProperty(named = "spring.profiles.active", matches = "postgres")
+@ContextConfiguration
+@Transactional
+@ExtendWith(SpringExtension.class)
+public class PostgresJsonConvertersIntegrationTests {
+
+    @Profile("postgres")
+    @Configuration
+    @Import(TestConfiguration.class)
+    @EnableJdbcRepositories(considerNestedRepositories = true,
+            includeFilters = @ComponentScan.Filter(value = CustomerRepository.class, type = FilterType.ASSIGNABLE_TYPE))
+    static class Config {
+
+        private final ObjectMapper objectMapper = new ObjectMapper();
+
+        @Bean
+        Class> testClass() {
+            return PostgresJsonConvertersIntegrationTests.class;
+        }
+
+        @WritingConverter
+        static class PersonDataWritingConverter extends AbstractPostgresJsonWritingConverter {
+
+            public PersonDataWritingConverter(ObjectMapper objectMapper) {
+                super(objectMapper, true);
+            }
+        }
+
+        @ReadingConverter
+        static class PersonDataReadingConverter extends AbstractPostgresJsonReadingConverter {
+            public PersonDataReadingConverter(ObjectMapper objectMapper) {
+                super(objectMapper, PersonData.class);
+            }
+        }
+
+        @WritingConverter
+        static class SessionDataWritingConverter extends AbstractPostgresJsonWritingConverter {
+            public SessionDataWritingConverter(ObjectMapper objectMapper) {
+                super(objectMapper, true);
+            }
+        }
+
+        @ReadingConverter
+        static class SessionDataReadingConverter extends AbstractPostgresJsonReadingConverter {
+            public SessionDataReadingConverter(ObjectMapper objectMapper) {
+                super(objectMapper, SessionData.class);
+            }
+        }
+
+        private List