-
Bug
-
Resolution: Done
-
Major
-
28.0.1.Final, 29.0.0.Beta1, 29.0.0.Final
-
None
The Hibernate module does not have access to the Jackson module in modules/system/layers/base/org/hibernate/main/module.xml.
This is a problem when using Hibernates JSON Mapping feature, which uses Jackson: https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#basic-mapping-json
Issue when querying entities
When you query an entity that has a field annotated with @JdbcTypeCode(SqlTypes.JSON) you get the following exception, because Hibernate cannot see the Jackson classes:
org.hibernate.HibernateException: Could not find a FormatMapper for the JSON format, which is required for mapping JSON types. JSON FormatMapper configuration is automatic, but requires that you have either Jackson or a JSONB implementation like Yasson on the class path. at org.hibernate@6.2.1.Final//org.hibernate.internal.FastSessionServices.getJsonFormatMapper(FastSessionServices.java:387) at org.hibernate@6.2.1.Final//org.hibernate.type.descriptor.jdbc.JsonJdbcType.fromString(JsonJdbcType.java:86) at org.hibernate@6.2.1.Final//org.hibernate.type.descriptor.jdbc.JsonJdbcType$2.doExtract(JsonJdbcType.java:140) at org.hibernate@6.2.1.Final//org.hibernate.type.descriptor.jdbc.BasicExtractor.extract(BasicExtractor.java:44) at org.hibernate@6.2.1.Final//org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.readCurrentRowValues(JdbcValuesResultSetImpl.java:262) at org.hibernate@6.2.1.Final//org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.advance(JdbcValuesResultSetImpl.java:243) at org.hibernate@6.2.1.Final//org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.processNext(JdbcValuesResultSetImpl.java:84) at org.hibernate@6.2.1.Final//org.hibernate.sql.results.jdbc.internal.AbstractJdbcValues.next(AbstractJdbcValues.java:29) at org.hibernate@6.2.1.Final//org.hibernate.sql.results.internal.RowProcessingStateStandardImpl.next(RowProcessingStateStandardImpl.java:62) at org.hibernate@6.2.1.Final//org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:198) at org.hibernate@6.2.1.Final//org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:33) at org.hibernate@6.2.1.Final//org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:362) at org.hibernate@6.2.1.Final//org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:168) at org.hibernate@6.2.1.Final//org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.list(JdbcSelectExecutorStandardImpl.java:93) at org.hibernate@6.2.1.Final//org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:31) at org.hibernate@6.2.1.Final//org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$0(ConcreteSqmSelectQueryPlan.java:109) at org.hibernate@6.2.1.Final//org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:302) at org.hibernate@6.2.1.Final//org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:243) at org.hibernate@6.2.1.Final//org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:521) at org.hibernate@6.2.1.Final//org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:367) at org.hibernate@6.2.1.Final//org.hibernate.query.sqm.internal.QuerySqmImpl.list(QuerySqmImpl.java:1084) at org.hibernate@6.2.1.Final//org.hibernate.query.Query.getResultList(Query.java:119)
Issue when using a custom JSON FormatMapper
If you try to supply a custom JSON-FormatMapper (as described in https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#misc-options) by adding the following to your persistence.xml:
<property name="hibernate.type.json_format_mapper" value="MyJsonFormatMapper" />
Then the deployment fails with the following error:
{"WFLYCTL0062: Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" => {"WFLYCTL0080: Failed services" => {"jboss.persistenceunit.\"my-app.war#MY_PERSISTENCE_UNIT\"" => "java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonProcessingException from [Module \"org.hibernate\" version 6.2.1.Final from local module loader @331acdad (finder: local module finder @41d426b5 (roots: wildfly\\modules,wildfly\\modules\\system\\layers\\base))]"}}}}
Here is the class MyJsonFormatMapper for reference:
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.format.FormatMapper; import org.hibernate.type.format.jackson.JacksonJsonFormatMapper; import com.fasterxml.jackson.databind.ObjectMapper; public class MyJsonFormatMapper implements FormatMapper { private final FormatMapper delegate = new JacksonJsonFormatMapper(new ObjectMapper()); @Override public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) { return delegate.fromString(charSequence, javaType, wrapperOptions); } @Override public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) { return delegate.toString(value, javaType, wrapperOptions); } }
Proposed solution for JSON
I can resolve the issue by adding the following two dependencies to the file modules/system/layers/base/org/hibernate/main/module.xml:
<module name="com.fasterxml.jackson.core.jackson-core"/> <module name="com.fasterxml.jackson.core.jackson-databind"/>
Issue when using a custom XML FormatMapper
If you try to supply a custom XML-FormatMapper (as described in https://docs.jboss.org/hibernate/orm/6.2/userguide/html_single/Hibernate_User_Guide.html#misc-options) by adding the following to your persistence.xml:
<property name="hibernate.type.xml_format_mapper" value="MyXmlFormatMapper" />
Then the deployment fails with the following error:
{"WFLYCTL0062: Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" => {"WFLYCTL0080: Failed services" => {"jboss.persistenceunit.\"my-app.war#MY_PERSISTENCE_UNIT\"" => "java.lang.NoClassDefFoundError: com/fasterxml/jackson/dataformat/xml/XmlMapper Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/dataformat/xml/XmlMapper Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.dataformat.xml.XmlMapper from [Module \"org.hibernate\" version 6.2.1.Final from local module loader @22295ec4 (finder: local module finder @5adb0db3 (roots: wildfly\\modules,wildfly\\modules\\system\\layers\\base))]"}}}}
Here is the class MyXmlFormatMapper for reference:
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.format.FormatMapper; import org.hibernate.type.format.jackson.JacksonXmlFormatMapper; public class MyXmlFormatMapper implements FormatMapper { private final FormatMapper delegate = new JacksonXmlFormatMapper(); @Override public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) { return delegate.fromString(charSequence, javaType, wrapperOptions); } @Override public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) { return delegate.toString(value, javaType, wrapperOptions); } }
This error occurs even when the war file contains jackson-dataformat-xml-2.14.2.jar in it's WEB-INF/lib directory so I suspect that the hibernate module does not gain access to user provided libraries. I suspect that this may also be a problem, if you use a FormatMapper for JSON that uses some library other than Jackson. Maybe the FormatMapper class is loaded with the hibernate module classloader but shoud be loaded by the application classloader? I don't know how WildFly loads classes, this is just a thought.
Since there is no module com.fasterxml.jackson.dataformat.jackson-dataformat-xml I didn't find a fix to use a FormatMapper for XML, but luckily I only need JSON support for now. Still it would be great if I didn't have to manually patch the WildFly installation whenever a new version comes out.
Closing thoughts
Even if adding the dependencies to modules/system/layers/base/org/hibernate/main/module.xml does not fix the problem with a custom XML-FormatMapper I think it would still be worth it to include the two lines in the next WildFly release to at least support JSON via Jackson until a full fix is found.
- is cloned by
-
JBEAP-27250 (8.0.z) JPA/Hibernate: cannot write to a JSONB column
- Resolved