In Hibernate 5.x I used to register hibernate type like:
<code>import java.sql.Types;
import org.hibernate.dialect.PostgreSQL10Dialect;
import io.hypersistence.utils.hibernate.type.array.IntArrayType;
import io.hypersistence.utils.hibernate.type.array.StringArrayType;
import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeStringType;
import io.hypersistence.utils.hibernate.type.json.JsonStringType;
public class PostgreSQLJsonDialect extends PostgreSQL10Dialect {
public PostgreSQLJsonDialect() {
this.registerHibernateType(Types.OTHER, StringArrayType.class.getName());
this.registerHibernateType(Types.OTHER, IntArrayType.class.getName());
this.registerHibernateType(Types.OTHER, JsonStringType.class.getName());
this.registerHibernateType(Types.OTHER, JsonBinaryType.class.getName());
this.registerHibernateType(Types.OTHER, JsonNodeBinaryType.class.getName());
this.registerHibernateType(Types.OTHER, JsonNodeStringType.class.getName());
<code>import java.sql.Types;
import org.hibernate.dialect.PostgreSQL10Dialect;
import io.hypersistence.utils.hibernate.type.array.IntArrayType;
import io.hypersistence.utils.hibernate.type.array.StringArrayType;
import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeStringType;
import io.hypersistence.utils.hibernate.type.json.JsonStringType;
public class PostgreSQLJsonDialect extends PostgreSQL10Dialect {
public PostgreSQLJsonDialect() {
super();
this.registerHibernateType(Types.OTHER, StringArrayType.class.getName());
this.registerHibernateType(Types.OTHER, IntArrayType.class.getName());
this.registerHibernateType(Types.OTHER, JsonStringType.class.getName());
this.registerHibernateType(Types.OTHER, JsonBinaryType.class.getName());
this.registerHibernateType(Types.OTHER, JsonNodeBinaryType.class.getName());
this.registerHibernateType(Types.OTHER, JsonNodeStringType.class.getName());
}
}
</code>
import java.sql.Types;
import org.hibernate.dialect.PostgreSQL10Dialect;
import io.hypersistence.utils.hibernate.type.array.IntArrayType;
import io.hypersistence.utils.hibernate.type.array.StringArrayType;
import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeStringType;
import io.hypersistence.utils.hibernate.type.json.JsonStringType;
public class PostgreSQLJsonDialect extends PostgreSQL10Dialect {
public PostgreSQLJsonDialect() {
super();
this.registerHibernateType(Types.OTHER, StringArrayType.class.getName());
this.registerHibernateType(Types.OTHER, IntArrayType.class.getName());
this.registerHibernateType(Types.OTHER, JsonStringType.class.getName());
this.registerHibernateType(Types.OTHER, JsonBinaryType.class.getName());
this.registerHibernateType(Types.OTHER, JsonNodeBinaryType.class.getName());
this.registerHibernateType(Types.OTHER, JsonNodeStringType.class.getName());
}
}
But post migration, I can no longer register these types.
the above code is now changed to:
<code>import org.hibernate.dialect.PostgresPlusDialect;
public class PostgreSQLJsonDialect extends PostgresPlusDialect {
public PostgreSQLJsonDialect() {
<code>import org.hibernate.dialect.PostgresPlusDialect;
public class PostgreSQLJsonDialect extends PostgresPlusDialect {
public PostgreSQLJsonDialect() {
super();
}
}
</code>
import org.hibernate.dialect.PostgresPlusDialect;
public class PostgreSQLJsonDialect extends PostgresPlusDialect {
public PostgreSQLJsonDialect() {
super();
}
}
I have an entity which previously looked like:
<code>import com.fasterxml.jackson.databind.JsonNode;
import io.hypersistence.utils.hibernate.type.json.JsonType;
typeClass = JsonBinaryType.class
@Column(name = "output", columnDefinition = "jsonb")
<code>import com.fasterxml.jackson.databind.JsonNode;
import io.hypersistence.utils.hibernate.type.json.JsonType;
....
@TypeDef(
name = "jsonb",
typeClass = JsonBinaryType.class
)
public class Work {
@Column(name = "output", columnDefinition = "jsonb")
@JsonProperty("output")
@Type(type = "jsonb")
private JsonNode output;
......
......
</code>
import com.fasterxml.jackson.databind.JsonNode;
import io.hypersistence.utils.hibernate.type.json.JsonType;
....
@TypeDef(
name = "jsonb",
typeClass = JsonBinaryType.class
)
public class Work {
@Column(name = "output", columnDefinition = "jsonb")
@JsonProperty("output")
@Type(type = "jsonb")
private JsonNode output;
......
......
currently after the migration it looks like:
<code>import com.fasterxml.jackson.databind.JsonNode;
import io.hypersistence.utils.hibernate.type.json.JsonType;
@Column(name = "output", columnDefinition = "jsonb")
<code>import com.fasterxml.jackson.databind.JsonNode;
import io.hypersistence.utils.hibernate.type.json.JsonType;
....
public class Work {
@Column(name = "output", columnDefinition = "jsonb")
@JsonProperty("output")
@Type(JsonType.class)
private JsonNode output;
......
......
</code>
import com.fasterxml.jackson.databind.JsonNode;
import io.hypersistence.utils.hibernate.type.json.JsonType;
....
public class Work {
@Column(name = "output", columnDefinition = "jsonb")
@JsonProperty("output")
@Type(JsonType.class)
private JsonNode output;
......
......
and my repository code looks like:
<code>public interface WorkRepository extends JpaRepository<Task, UUID> {
@Query(value = "SELECT output FROM work WHERE job_id = :jobId AND type = :type ORDER BY ended_at DESC LIMIT 1",
Optional<JsonNode> getLatestOutput(String type, UUID jobId);
<code>public interface WorkRepository extends JpaRepository<Task, UUID> {
@Query(value = "SELECT output FROM work WHERE job_id = :jobId AND type = :type ORDER BY ended_at DESC LIMIT 1",
nativeQuery = true)
Optional<JsonNode> getLatestOutput(String type, UUID jobId);
}
</code>
public interface WorkRepository extends JpaRepository<Task, UUID> {
@Query(value = "SELECT output FROM work WHERE job_id = :jobId AND type = :type ORDER BY ended_at DESC LIMIT 1",
nativeQuery = true)
Optional<JsonNode> getLatestOutput(String type, UUID jobId);
}
I want to be able to fetch the data in JsonNode format.
I tried to resolveSqlTypeDescriptor like this:
<code>import org.hibernate.dialect.PostgresPlusDialect;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeStringType;
import io.hypersistence.utils.hibernate.type.json.JsonStringType;
import io.hypersistence.utils.hibernate.type.json.JsonType;
public class PostgreSQLJsonDialect extends PostgresPlusDialect {
public PostgreSQLJsonDialect() {
final TypeConfiguration typeConfiguration = new TypeConfiguration();
final JdbcTypeRegistry jdbcTypeRegistry = new JdbcTypeRegistry(typeConfiguration);
this.resolveSqlTypeDescriptor(new JsonBinaryType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonNodeBinaryType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonStringType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonNodeStringType().getName(), 0, 0, 0, jdbcTypeRegistry);
public JdbcType resolveSqlTypeDescriptor(final String columnTypeName, int jdbcTypeCode, final int precision, final int scale, final JdbcTypeRegistry jdbcTypeRegistry) {
jdbcTypeCode = SqlTypes.OTHER;
return super.resolveSqlTypeDescriptor(columnTypeName, jdbcTypeCode, precision, scale, jdbcTypeRegistry);
<code>import org.hibernate.dialect.PostgresPlusDialect;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeStringType;
import io.hypersistence.utils.hibernate.type.json.JsonStringType;
import io.hypersistence.utils.hibernate.type.json.JsonType;
public class PostgreSQLJsonDialect extends PostgresPlusDialect {
public PostgreSQLJsonDialect() {
super();
final TypeConfiguration typeConfiguration = new TypeConfiguration();
final JdbcTypeRegistry jdbcTypeRegistry = new JdbcTypeRegistry(typeConfiguration);
this.resolveSqlTypeDescriptor(new JsonBinaryType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonNodeBinaryType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonStringType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonNodeStringType().getName(), 0, 0, 0, jdbcTypeRegistry);
}
@Override
public JdbcType resolveSqlTypeDescriptor(final String columnTypeName, int jdbcTypeCode, final int precision, final int scale, final JdbcTypeRegistry jdbcTypeRegistry) {
jdbcTypeCode = SqlTypes.OTHER;
return super.resolveSqlTypeDescriptor(columnTypeName, jdbcTypeCode, precision, scale, jdbcTypeRegistry);
}
}
</code>
import org.hibernate.dialect.PostgresPlusDialect;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeBinaryType;
import io.hypersistence.utils.hibernate.type.json.JsonNodeStringType;
import io.hypersistence.utils.hibernate.type.json.JsonStringType;
import io.hypersistence.utils.hibernate.type.json.JsonType;
public class PostgreSQLJsonDialect extends PostgresPlusDialect {
public PostgreSQLJsonDialect() {
super();
final TypeConfiguration typeConfiguration = new TypeConfiguration();
final JdbcTypeRegistry jdbcTypeRegistry = new JdbcTypeRegistry(typeConfiguration);
this.resolveSqlTypeDescriptor(new JsonBinaryType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonNodeBinaryType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonStringType().getName(), 0, 0, 0, jdbcTypeRegistry);
this.resolveSqlTypeDescriptor(new JsonNodeStringType().getName(), 0, 0, 0, jdbcTypeRegistry);
}
@Override
public JdbcType resolveSqlTypeDescriptor(final String columnTypeName, int jdbcTypeCode, final int precision, final int scale, final JdbcTypeRegistry jdbcTypeRegistry) {
jdbcTypeCode = SqlTypes.OTHER;
return super.resolveSqlTypeDescriptor(columnTypeName, jdbcTypeCode, precision, scale, jdbcTypeRegistry);
}
}
But this is still not working and I am getting an error:
<code>[EXCEPTION]: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.fasterxml.jackson.databind.JsonNode] at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175) at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:305) at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:233) at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:240) at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:174) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:152) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:137) at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136) at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
<code>[EXCEPTION]: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.fasterxml.jackson.databind.JsonNode] at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175) at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:305) at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:233) at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:240) at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:174) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:152) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:137) at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136) at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
</code>
[EXCEPTION]: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.fasterxml.jackson.databind.JsonNode] at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175) at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:305) at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:233) at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:240) at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:174) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:152) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:137) at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136) at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
How can I register JsonNode so that I am able to fetch the data in JsonNode format?
PS: This question was also asked in the hibernate forum:
https://discourse.hibernate.org/t/mapping-for-jsonnode-in-hibernate-6-2-fails-after-migration-from-hibernate-5-x/9416