Skip to content

HHH-17404 : Add support of reading/writing from/to special source/target in FormatMapper #9629

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

Open
wants to merge 81 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
e1042c2
HHH-17404 : Support reading/writing from/to special source/target in …
ejannett Dec 13, 2024
2e23844
HHH-17404: Jakarta annotation souuport for Jackson
BidyadharM Dec 17, 2024
ccf786a
HHH-17404: align JDBC dependencies version
ejannett Dec 16, 2024
d361486
HHH-17404 : use OsonEvent to deal with temporal
ejannett Dec 17, 2024
c6dac4c
HHH-17404 : fix Boolean convertion
ejannett Dec 17, 2024
2e494d8
HHH-17404 : fix UUID deserialization
ejannett Dec 18, 2024
9242188
HHH-17404 : move to OracleJSONParser
ejannett Dec 18, 2024
9655e22
HHH-17404 : implement array csae in embeddable deserialization
ejannett Dec 18, 2024
de0066b
HHH-17404 : fix NPE while parsing DECIMAL
ejannett Dec 19, 2024
31e584b
HHH-17404 : fix dates and URLs
ejannett Dec 19, 2024
8f46f0f
HHH-17404 : fix handle of VALUE_INTERVALYM
ejannett Dec 20, 2024
6b83420
HHH-17404: Add serializer for Embeddable and OracleDurationJdbcType
BidyadharM Jan 6, 2025
db5866c
HHH-17404 : move to fromString() in case of string event received
ejannett Dec 23, 2024
ebf0ad5
HHH-17404 : Add OSON document handler for embeddabe processing
ejannett Jan 3, 2025
5d445c8
HHH-17404: More fixes
BidyadharM Jan 6, 2025
cfe8a0a
HHH-17404: Serialization for additional types
BidyadharM Jan 7, 2025
3078daa
HHH-17404 : add more date related types to document handler
ejannett Jan 6, 2025
a33f519
HHH-17404 : use of BigDecimal in case of DECIMAL OSON event received …
ejannett Jan 7, 2025
93caae7
HHH-17404 : fix toString in mapper
ejannett Jan 7, 2025
3e0283c
HHH-17404 InternalDS Support for duration
BidyadharM Jan 8, 2025
2c613bb
HHH-17404-Replace the embeddable serialization approach.
BidyadharM Jan 9, 2025
09ca64f
HHH-17404 : fix issue with sub-embeddables
ejannett Jan 8, 2025
edd348b
HHH-17404 : remove creation of ObjectMapper in the Oson type to rely …
ejannett Jan 8, 2025
9c2c2f8
HHH-17404 : fix OsonFactory for extaction
ejannett Jan 8, 2025
8f22ddb
HHH-17404 : fix OracleDurationJdbcType
ejannett Jan 9, 2025
6c32545
HHH-17404 - Fix Nested Embeddable Tests
BidyadharM Jan 9, 2025
41d94a2
HHH-17404- Fix Array Embeddables.
BidyadharM Jan 10, 2025
b1f5cf2
HHH-17404- Additional Fixes for Duration.
BidyadharM Jan 10, 2025
2b4e40a
HHH-17404 - Add JSON_ARRAY serializer
BidyadharM Jan 11, 2025
c2b2105
HHH-17404- Fix duration types
BidyadharM Jan 15, 2025
3ae531c
HHH-17404 : add JSON document handler for serialization
ejannett Jan 14, 2025
8f0b25c
HHH-17404 - Fix extractor
BidyadharM Jan 15, 2025
80be38b
HHH-17404- UUID fix
BidyadharM Jan 15, 2025
046b4de
HHH-17404 : remove unwanted committed settings
ejannett Jan 15, 2025
3f0772f
HHH-17404 : remove unused methods
ejannett Jan 15, 2025
bc13d8b
HHH-17404 : Rollback Test Entity changes and JsonMapping tests fix.
BidyadharM Jan 15, 2025
d0e4b5a
HHH-17404 : general cleanup before PR
ejannett Jan 16, 2025
3ea2b39
HHH-17404- Rollback OracleUserDefinedTypeExporter changes
BidyadharM Jan 17, 2025
68d07c1
HHH-17404- Aggregate instance creation fix.
BidyadharM Jan 17, 2025
1b4b914
HHH-17404 : fix aggregatesupport for "no-extension" case
ejannett Jan 17, 2025
1084c23
HHH-17404 : fix condition on aggregate support load
ejannett Jan 17, 2025
4641807
HHH-17404 : refactor OSON formatMapper to align on JSON one.
ejannett Jan 18, 2025
9ecc283
HHH-17404 : applies some review comments
ejannett Jan 21, 2025
25db63c
HHH-17404 : implement JSON document readers and writers for OSON exte…
ejannett Jan 29, 2025
0088b3c
HHH-17404 : removed dead code
ejannett Jan 29, 2025
a2ab3cb
HHH-17404- Remove DURATION mapping to INTERVALDS
BidyadharM Feb 11, 2025
ddf7cf9
HHH-17404- Remove DURATION mapping to INTERVALDS (2)
BidyadharM Feb 11, 2025
9921759
HHH-17404: Undo Test Skips
BidyadharM Feb 11, 2025
558872a
HHH-17404 : applied eview comment
ejannett Feb 18, 2025
4f837eb
HHH-17404 : applied review comments. removed use of valueIsAString
ejannett Mar 13, 2025
4ba2143
HHH-17404 : fix build after merge
ejannett Mar 26, 2025
c978aa9
HHH-17404 : refactor StringJsonDocumentReader to remove usage of Char…
ejannett Mar 26, 2025
7b1f19b
HHH-17404 : Address review comment to remove try-catch for SqlTypes.T…
BidyadharM Mar 27, 2025
3ec7af9
HHH-17404 add flag to disable OSON extension
ejannett Mar 27, 2025
60e7ede
HHH-17404 : Since thhe UUID is stored as string , retrieve it accordi…
BidyadharM Mar 28, 2025
7c0dcf6
HHH-17404 remove use of reflection
ejannett Apr 1, 2025
4fab88e
HHH-17404 : add schema compatibility test
ejannett Apr 7, 2025
28b8382
HHH-17404 : Removed Duration mapping to intervalDS misssed during pre…
BidyadharM Apr 9, 2025
5464593
HHH-17404 rename oson flag in oracle dialect
ejannett Apr 9, 2025
c944878
HHH-17404 add array of embeddable support
ejannett Apr 15, 2025
829d16d
HHH-17404 Fix compile errors
beikov Apr 17, 2025
d853847
HHH-17404 Address dialect and aggregate support comments
beikov Apr 17, 2025
ee5fcac
HHH-17404 Address issues in StringJsonDocumentReader
beikov Apr 17, 2025
ac1af27
HHH-17404 Cleanup JsonHelper and fix nested parsing
beikov Apr 17, 2025
7a45365
HHH-17404 Cleanup JdbcTypes and Jackson/OSON availability detection
beikov Apr 17, 2025
989be0b
HHH-17404 Parameterize DDL type for tests
beikov Apr 17, 2025
ec6929d
HHH-17404 add compatibility test
ejannett Apr 30, 2025
f0dbed7
HHH-17404 Oson compatibility test fixes
mbellade Apr 30, 2025
858a8ee
HHH-17404 Apply code-style to OracleOsonJdbcType and misc cleanups
mbellade Apr 30, 2025
8af30e2
HHH-17404 rebase with upstream
ejannett Apr 30, 2025
9f4a543
HHH-14707 fix code style
ejannett Apr 30, 2025
cd1f484
HHH-14707 Fix xml embeddable aggregate array support
mbellade Apr 30, 2025
33cfce6
HHH-17404 code style
ejannett Apr 30, 2025
d985887
HHH-17404 fix code scna warning about switch default case
ejannett May 2, 2025
851e2a3
HHH-17404 enhance compatibility test on type chakcing
ejannett May 2, 2025
d591b74
HHH-17404 add comment in the what's new doc
ejannett May 6, 2025
d17708a
HHH-17404 add test claeanup phase
ejannett May 16, 2025
4dd7e0c
HHH-17404 rebase with upstream
ejannett Jun 6, 2025
625fcdf
HHH-17404 add new contributor to AUTHORS list
ejannett Jun 6, 2025
2ff0032
HHH-17404 fix merge regresssion about struct support
ejannett Jun 13, 2025
a9d4756
HHH-17404 fix regression on OracleDialect on timeouts
ejannett Jun 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# Corporate contributors

Red Hat, Inc.
Oracle, Corporation.

# Individual contributors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
import org.hibernate.stat.Statistics;
import org.hibernate.type.format.FormatMapper;
import org.hibernate.type.format.jackson.JacksonIntegration;
import org.hibernate.type.format.jaxb.JaxbXmlFormatMapper;

import jakarta.persistence.criteria.Nulls;
Expand All @@ -93,6 +94,7 @@
import static org.hibernate.cfg.CacheSettings.JPA_SHARED_CACHE_RETRIEVE_MODE;
import static org.hibernate.cfg.CacheSettings.JPA_SHARED_CACHE_STORE_MODE;
import static org.hibernate.cfg.CacheSettings.QUERY_CACHE_LAYOUT;
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_OSON_DISABLED;
import static org.hibernate.cfg.PersistenceSettings.UNOWNED_ASSOCIATION_TRANSIENT_CHECK;
import static org.hibernate.cfg.QuerySettings.DEFAULT_NULL_ORDERING;
import static org.hibernate.cfg.QuerySettings.JSON_FUNCTIONS_ENABLED;
Expand All @@ -112,6 +114,7 @@
import static org.hibernate.jpa.internal.util.CacheModeHelper.interpretCacheMode;
import static org.hibernate.jpa.internal.util.ConfigurationHelper.getFlushMode;
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.getXMLJacksonFormatMapperOrNull;
import static org.hibernate.type.format.jakartajson.JakartaJsonIntegration.getJakartaJsonBFormatMapperOrNull;

Expand Down Expand Up @@ -305,8 +308,10 @@ public SessionFactoryOptionsBuilder(StandardServiceRegistry serviceRegistry, Boo

jsonFormatMapper = determineJsonFormatMapper(
settings.get( AvailableSettings.JSON_FORMAT_MAPPER ),
!getBoolean( ORACLE_OSON_DISABLED ,settings),
strategySelector
);

xmlFormatMapper = determineXmlFormatMapper(
settings.get( AvailableSettings.XML_FORMAT_MAPPER ),
strategySelector,
Expand Down Expand Up @@ -787,12 +792,16 @@ private PhysicalConnectionHandlingMode interpretConnectionHandlingMode(
.getDefaultConnectionHandlingMode();
}

private static FormatMapper determineJsonFormatMapper(Object setting, StrategySelector strategySelector) {
private static FormatMapper determineJsonFormatMapper(Object setting, boolean osonExtensionEnabled, StrategySelector strategySelector) {
return strategySelector.resolveDefaultableStrategy(
FormatMapper.class,
setting,
(Callable<FormatMapper>) () -> {
final FormatMapper jsonJacksonFormatMapper = getJsonJacksonFormatMapperOrNull();
// Prefer the OSON Jackson FormatMapper by default if available
final FormatMapper jsonJacksonFormatMapper =
(osonExtensionEnabled && JacksonIntegration.isJacksonOsonExtensionAvailable())
? getOsonJacksonFormatMapperOrNull()
: getJsonJacksonFormatMapperOrNull();
return jsonJacksonFormatMapper != null ? jsonJacksonFormatMapper : getJakartaJsonBFormatMapperOrNull();
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
import org.hibernate.type.format.FormatMapper;
import org.hibernate.type.format.jackson.JacksonIntegration;
import org.hibernate.type.format.jackson.JacksonJsonFormatMapper;
import org.hibernate.type.format.jackson.JacksonOsonFormatMapper;
import org.hibernate.type.format.jackson.JacksonXmlFormatMapper;
import org.hibernate.type.format.jaxb.JaxbXmlFormatMapper;
import org.hibernate.type.format.jakartajson.JsonBJsonFormatMapper;
Expand Down Expand Up @@ -303,14 +305,21 @@ private static void addCacheKeysFactories(StrategySelectorImpl strategySelector)
private static void addJsonFormatMappers(StrategySelectorImpl strategySelector) {
strategySelector.registerStrategyImplementor(
FormatMapper.class,
JacksonJsonFormatMapper.SHORT_NAME,
JacksonJsonFormatMapper.class
JsonBJsonFormatMapper.SHORT_NAME,
JsonBJsonFormatMapper.class
);
strategySelector.registerStrategyImplementor(
FormatMapper.class,
JsonBJsonFormatMapper.SHORT_NAME,
JsonBJsonFormatMapper.class
JacksonJsonFormatMapper.SHORT_NAME,
JacksonJsonFormatMapper.class
);
if ( JacksonIntegration.isJacksonOsonExtensionAvailable() ) {
strategySelector.registerStrategyImplementor(
FormatMapper.class,
JacksonOsonFormatMapper.SHORT_NAME,
JacksonOsonFormatMapper.class
);
}
}

private static void addXmlFormatMappers(StrategySelectorImpl strategySelector) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ public interface DialectSpecificSettings {
*/
String ORACLE_USE_BINARY_FLOATS = "hibernate.dialect.oracle.use_binary_floats";

/**
* Specifies whether usage of the Oracle JSON binary format (also known as OSON) should be disabled.
* <p>
* Starting in 21c, if the ojdbc-provider-jackson-oson extension is available, JSON data in an oracle
* database is stored using the OSON binary format. This setting can be used to fallback to the old implementation
* based on String serialization.
*
* @settingDefault {@code false}
* @since 7.0
*
* @see <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/json-oracle-database.html">Orace OSON format</a>
* @see <a href="https://github.com/oracle/ojdbc-extensions/blob/main/ojdbc-provider-jackson-oson/README.md">Jackson OSON provider</a>
*/
String ORACLE_OSON_DISABLED = "hibernate.dialect.oracle.oson_format_disabled";

/**
* Specifies whether the {@code ansinull} setting is enabled on Sybase.
* <p>
Expand Down

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ejannett please add the Oracle Copyright to all files you modify:
Copyright © 2025, Oracle and/or its affiliates.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.hibernate.Length;
import org.hibernate.QueryTimeoutException;
import org.hibernate.Timeouts;
import org.hibernate.QueryTimeoutException;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.aggregate.AggregateSupport;
Expand Down Expand Up @@ -115,15 +116,19 @@
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jboss.logging.Logger;

import static java.util.regex.Pattern.CASE_INSENSITIVE;
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_USE_BINARY_FLOATS;
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_OSON_DISABLED;
import static org.hibernate.dialect.type.OracleJdbcHelper.getArrayJdbcTypeConstructor;
import static org.hibernate.dialect.type.OracleJdbcHelper.getNestedTableJdbcTypeConstructor;
import static org.hibernate.dialect.DialectLogging.DIALECT_LOGGER;
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode;
import static org.hibernate.internal.util.StringHelper.isEmpty;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
import static org.hibernate.query.common.TemporalUnit.DAY;
import static org.hibernate.query.common.TemporalUnit.HOUR;
import static org.hibernate.query.common.TemporalUnit.MINUTE;
Expand Down Expand Up @@ -213,6 +218,7 @@ protected void applyAggregateColumnCheck(StringBuilder buf, AggregateColumn aggr

// Is the database accessed using a database service protected by Application Continuity.
protected final boolean applicationContinuity;

protected final int driverMajorVersion;
protected final int driverMinorVersion;
private boolean useBinaryFloat;
Expand All @@ -234,13 +240,13 @@ public OracleDialect(DialectResolutionInfo info) {
this( info, OracleServerConfiguration.fromDialectResolutionInfo( info ) );
}

public OracleDialect(DialectResolutionInfo info, OracleServerConfiguration configuration) {
public OracleDialect(DialectResolutionInfo info, OracleServerConfiguration serverConfiguration) {
super( info );
autonomous = configuration.isAutonomous();
extended = configuration.isExtended();
applicationContinuity = configuration.isApplicationContinuity();
driverMinorVersion = configuration.getDriverMinorVersion();
driverMajorVersion = configuration.getDriverMajorVersion();
autonomous = serverConfiguration.isAutonomous();
extended = serverConfiguration.isExtended();
applicationContinuity = serverConfiguration.isApplicationContinuity();
this.driverMinorVersion = serverConfiguration.getDriverMinorVersion();
this.driverMajorVersion = serverConfiguration.getDriverMajorVersion();
}

public boolean isAutonomous() {
Expand Down Expand Up @@ -278,11 +284,10 @@ public void appendBooleanValueString(SqlAppender appender, boolean bool) {

@Override
public void initializeFunctionRegistry(FunctionContributions functionContributions) {
super.initializeFunctionRegistry( functionContributions );
super.initializeFunctionRegistry(functionContributions);
final TypeConfiguration typeConfiguration = functionContributions.getTypeConfiguration();

final var functionFactory = new CommonFunctionFactory( functionContributions );

CommonFunctionFactory functionFactory = new CommonFunctionFactory(functionContributions);
functionFactory.ascii();
functionFactory.char_chr();
functionFactory.cosh();
Expand Down Expand Up @@ -839,6 +844,7 @@ protected void registerColumnTypes(TypeContributions typeContributions, ServiceR
}
// We need the DDL type during runtime to produce the proper encoding in certain functions
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( BIT, "number(1,0)", this ) );

}

@Override
Expand Down Expand Up @@ -1002,8 +1008,24 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
}

if ( getVersion().isSameOrAfter( 21 ) ) {
typeContributions.contributeJdbcType( OracleJsonJdbcType.INSTANCE );
typeContributions.contributeJdbcTypeConstructor( OracleJsonArrayJdbcTypeConstructor.NATIVE_INSTANCE );
final boolean osonDisabled = getBoolean( ORACLE_OSON_DISABLED, configurationService.getSettings() );
if ( !osonDisabled && OracleJdbcHelper.isOsonAvailable( serviceRegistry ) ) {
// We must check that that extension is available and actually used.
typeContributions.contributeJdbcType( OracleOsonJdbcType.INSTANCE );
typeContributions.contributeJdbcTypeConstructor( OracleOsonArrayJdbcTypeConstructor.INSTANCE );

DIALECT_LOGGER.log( Logger.Level.DEBUG, "Oracle OSON extension enabled" );
}
else {
if ( osonDisabled ) {
DIALECT_LOGGER.log( Logger.Level.DEBUG, "Oracle OSON extension disabled" );
}
else {
DIALECT_LOGGER.log( Logger.Level.DEBUG, "Oracle OSON extension not available" );
}
typeContributions.contributeJdbcType( OracleJsonJdbcType.INSTANCE );
typeContributions.contributeJdbcTypeConstructor( OracleJsonArrayJdbcTypeConstructor.NATIVE_INSTANCE );
}
}
else {
typeContributions.contributeJdbcType( OracleJsonBlobJdbcType.INSTANCE );
Expand Down Expand Up @@ -1442,7 +1464,7 @@ public RowLockStrategy getWriteRowLockStrategy() {
}

@Override
public String getForUpdateNowaitString() {
public String getForUpdateNowaitString(){
return " for update nowait";
}

Expand Down Expand Up @@ -1671,10 +1693,10 @@ public String generatedAs(String generatedAs) {
}

@Override
public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData metadata)
public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData dbMetaData)
throws SQLException {
builder.setAutoQuoteInitialUnderscore( true );
return super.buildIdentifierHelper( builder, metadata );
return super.buildIdentifierHelper( builder, dbMetaData );
}

@Override
Expand Down
Loading
Loading