Mapping for JsonNode in Hibernate 6.2 fails after migration from Hibernate 5.x

In Hibernate 5.x I used to register hibernate type like:

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:

import org.hibernate.dialect.PostgresPlusDialect;

public class PostgreSQLJsonDialect extends PostgresPlusDialect {
	public PostgreSQLJsonDialect() {
		super();
	}
}

I have an entity which previously looked like:

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:

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:

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);

}

but I am getting an error:

[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)

How can I register JsonNode so that I am able to fetch the data in JsonNode format?

The single line of error logging you provided seems to point to an issue within the Spring Framework. This is an Hibernate forum, so if you think the error is caused by Hibernate please provide us with the full stack trace that shows where the exception occurs, otherwise I suggest asking the Spring folks for help.


This is the stack trace. But as you mentioned, after looking at it, this looks like spring framework issue to me as well.
If anyone in this forum has some idea, that would be really helpful.

I have also asked this question on stack-overflow as well.

Hi @anmol, did you find the issue or solution (workaround maybe)? If you did, can you share it?

@pyaqubzade yes. I did asked this question on stackoverflow as well and the hint in the post helped me solve the issue.

Here is the link: spring - Mapping for JsonNode fails after migrating to SpringBoot 3.x - Stack Overflow

I hope this might help.

@anmol thanks for the response. In my use case, we create a JSON response by using PostgreSQL’s json_agg() functions. So my table actually does not have any JSON type column. In my case, I manually injected (it is Spring application) the entity manager & called createNativeQuery() function on it like this:

        var jsonNodes = (ArrayNode) entityManager.createNativeQuery(MY_NATIVE_QUERY)
                .unwrap(NativeQuery.class)
                .addScalar("myJsonResult", ArrayNode.class)
                .getSingleResult();

In order it to work I also add this code to my custom dialect:

    @Override
    public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {

        typeContributions.contributeType(new JsonStringType(ArrayNode.class));

        super.contributeTypes(typeContributions, serviceRegistry);
    }