-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
HHH-19890 Add Jackson 3 FormatMapper support #11357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -101,10 +101,11 @@ | |
| import static org.hibernate.jpa.internal.util.CacheModeHelper.interpretCacheMode; | ||
| import static org.hibernate.jpa.internal.util.ConfigurationHelper.getFlushMode; | ||
| import static org.hibernate.stat.Statistics.DEFAULT_QUERY_STATISTICS_MAX_SIZE; | ||
| import static org.hibernate.type.format.jackson.JacksonIntegration.getJsonJackson3FormatMapperOrNull; | ||
| import static org.hibernate.type.format.jackson.JacksonIntegration.getJsonJacksonFormatMapperOrNull; | ||
| import static org.hibernate.type.format.jackson.JacksonIntegration.getOsonJacksonFormatMapperOrNull; | ||
| import static org.hibernate.type.format.jackson.JacksonIntegration.getXMLJackson3FormatMapperOrNull; | ||
| import static org.hibernate.type.format.jackson.JacksonIntegration.getXMLJacksonFormatMapperOrNull; | ||
| import static org.hibernate.type.format.jackson.JacksonIntegration.isJacksonOsonExtensionAvailable; | ||
| import static org.hibernate.type.format.jakartajson.JakartaJsonIntegration.getJakartaJsonBFormatMapperOrNull; | ||
|
|
||
| /** | ||
|
|
@@ -851,14 +852,25 @@ private static FormatMapper jsonFormatMapper(Object setting, boolean osonExtensi | |
| setting, | ||
| selector, | ||
| () -> { | ||
| final FormatMapper jackson3FormatMapper = getJsonJackson3FormatMapperOrNull( creationContext ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Defaulting to Jackson 3 if it's on the classpath might not be such a good idea since people might still want to keep using Jackson 2 for Hibernate ORM if it is also around. I would suggest to use Jackson 3 as fallback if Jackson 2 is not available. |
||
| if ( jackson3FormatMapper != null ) { | ||
| return jackson3FormatMapper; | ||
| } | ||
|
|
||
| // Prefer the OSON Jackson FormatMapper by default if available | ||
| final FormatMapper jsonJacksonFormatMapper = | ||
| osonExtensionEnabled && isJacksonOsonExtensionAvailable() | ||
| ? getOsonJacksonFormatMapperOrNull( creationContext ) | ||
| : getJsonJacksonFormatMapperOrNull( creationContext ); | ||
| return jsonJacksonFormatMapper != null | ||
| ? jsonJacksonFormatMapper | ||
| : getJakartaJsonBFormatMapperOrNull(); | ||
| final FormatMapper jacksonOsonFormatMapper = osonExtensionEnabled | ||
| ? getOsonJacksonFormatMapperOrNull( creationContext ) | ||
| : null; | ||
| if ( jacksonOsonFormatMapper != null ) { | ||
| return jacksonOsonFormatMapper; | ||
| } | ||
|
|
||
| final FormatMapper jacksonFormatMapper = getJsonJacksonFormatMapperOrNull( creationContext ); | ||
| if ( jacksonFormatMapper != null ) { | ||
| return jacksonFormatMapper; | ||
| } | ||
|
|
||
| return getJakartaJsonBFormatMapperOrNull(); | ||
| }, | ||
| creationContext | ||
| ); | ||
|
|
@@ -869,10 +881,17 @@ private static FormatMapper xmlFormatMapper(Object setting, StrategySelector sel | |
| setting, | ||
| selector, | ||
| () -> { | ||
| final FormatMapper jacksonFormatMapper = getXMLJacksonFormatMapperOrNull( creationContext ); | ||
| return jacksonFormatMapper != null | ||
| ? jacksonFormatMapper | ||
| : new JaxbXmlFormatMapper( legacyFormat ); | ||
| final FormatMapper jackson3FormatMapper = getXMLJackson3FormatMapperOrNull( creationContext ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as above, I would suggest to use Jackson 3 as fallback if Jackson 2 is not available. |
||
| if (jackson3FormatMapper != null) { | ||
| return jackson3FormatMapper; | ||
| } | ||
|
|
||
| final FormatMapper jacksonFormatMapper = getXMLJacksonFormatMapperOrNull( creationContext ); | ||
| if (jacksonFormatMapper != null) { | ||
| return jacksonFormatMapper; | ||
| } | ||
|
|
||
| return new JaxbXmlFormatMapper( legacyFormat ); | ||
| }, | ||
| creationContext | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| /* | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| * Copyright Red Hat Inc. and Hibernate Authors | ||
| */ | ||
| package org.hibernate.type.format.jackson; | ||
|
|
||
| import org.hibernate.type.descriptor.WrapperOptions; | ||
| import org.hibernate.type.descriptor.java.JavaType; | ||
| import org.hibernate.type.format.AbstractJsonFormatMapper; | ||
| import org.hibernate.type.format.FormatMapperCreationContext; | ||
| import tools.jackson.core.JacksonException; | ||
| import tools.jackson.core.JsonGenerator; | ||
| import tools.jackson.core.JsonParser; | ||
| import tools.jackson.databind.JacksonModule; | ||
| import tools.jackson.databind.cfg.MapperBuilder; | ||
| import tools.jackson.databind.json.JsonMapper; | ||
|
|
||
| import java.lang.reflect.Type; | ||
| import java.util.List; | ||
|
|
||
| /** | ||
| * @author Christian Beikov | ||
| * @author Yanming Zhou | ||
| * @author Nick Rayburn | ||
| */ | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if the previous author's need to be retained. This file was copied from the existing one that they were on. (I also don't need my name in here either unless it's the project standard, just tried to match what I copied from.) |
||
| public final class Jackson3JsonFormatMapper extends AbstractJsonFormatMapper { | ||
|
|
||
| public static final String SHORT_NAME = "jackson3"; | ||
|
|
||
| private final JsonMapper jsonMapper; | ||
|
|
||
| public Jackson3JsonFormatMapper() { | ||
| this( MapperBuilder.findModules( Jackson3JsonFormatMapper.class.getClassLoader() ) ); | ||
| } | ||
|
|
||
| public Jackson3JsonFormatMapper(FormatMapperCreationContext creationContext) { | ||
| this( JacksonIntegration.loadJackson3Modules( creationContext ) ); | ||
| } | ||
|
|
||
| private Jackson3JsonFormatMapper(List<JacksonModule> modules) { | ||
| this( JsonMapper.builderWithJackson2Defaults() | ||
| .addModules( modules ) | ||
| .build() | ||
| ); | ||
| } | ||
|
|
||
| public Jackson3JsonFormatMapper(JsonMapper jsonMapper) { | ||
| this.jsonMapper = jsonMapper; | ||
| } | ||
|
|
||
| @Override | ||
| public <T> void writeToTarget(T value, JavaType<T> javaType, Object target, WrapperOptions options) | ||
| throws JacksonException { | ||
| jsonMapper.writerFor( jsonMapper.constructType( javaType.getJavaType() ) ) | ||
| .writeValue( (JsonGenerator) target, value ); | ||
| } | ||
|
|
||
| @Override | ||
| public <T> T readFromSource(JavaType<T> javaType, Object source, WrapperOptions options) throws JacksonException { | ||
| return jsonMapper.readValue( (JsonParser) source, jsonMapper.constructType( javaType.getJavaType() ) ); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean supportsSourceType(Class<?> sourceType) { | ||
| return JsonParser.class.isAssignableFrom( sourceType ); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean supportsTargetType(Class<?> targetType) { | ||
| return JsonGenerator.class.isAssignableFrom( targetType ); | ||
| } | ||
|
|
||
| @Override | ||
| public <T> T fromString(CharSequence charSequence, Type type) { | ||
| try { | ||
| return jsonMapper.readValue( charSequence.toString(), jsonMapper.constructType( type ) ); | ||
| } | ||
| catch (JacksonException e) { | ||
| throw new IllegalArgumentException( "Could not deserialize string to java type: " + type, e ); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public <T> String toString(T value, Type type) { | ||
| try { | ||
| return jsonMapper.writerFor( jsonMapper.constructType( type ) ).writeValueAsString( value ); | ||
| } | ||
| catch (JacksonException e) { | ||
| throw new IllegalArgumentException( "Could not serialize object of java type: " + type, e ); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also mention what artifact is needed for Jackson 3?