hibernate-orm icon indicating copy to clipboard operation
hibernate-orm copied to clipboard

HHH-18312 Fix for Informix nationalized JDBC types support

Open VladoKuruc opened this issue 1 year ago • 3 comments

Solution similar to DB2Dialect, which was accepted for issue HHH-12753:

jdbcTypeRegistry.addDescriptor(Types.NCHAR, CharJdbcType.INSTANCE);
jdbcTypeRegistry.addDescriptor(Types.NVARCHAR, VarcharJdbcType.INSTANCE);
jdbcTypeRegistry.addDescriptor(Types.LONGNVARCHAR, LongVarcharJdbcType.INSTANCE);

This is not entirely correct, because in this way the table schema is also created directly with the type (CHAR / VARCHAR / LONGVARCHAR) even though the database supports the types (NCHAR / NVARCHAR / LONGNVARCHAR). Therefore, it is only necessary to replace calls to setNString() with setString() within the doBind() methods. There may be another way to solve this, so that the creation of the schema is preserved even with the data types NCHAR / NVARCHAR / LONGNVARCHAR and at the same time doBind() / doExtract() are used as with the basic types (getString() / setString()). Since the NCLOB data type does not exist, replacing CLOB seems fine to me.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion. For more information on licensing, please check here.


https://hibernate.atlassian.net/browse/HHH-18312

VladoKuruc avatar Jun 28 '24 15:06 VladoKuruc

There may be another way to solve this

Yeah, I hope so, since I don't like multiplying the JdbcTypes like this!

Solution similar to DB2Dialect, which was accepted for issue HHH-12753 ... This is not entirely correct

Ufff. So, it's not even correct for DB2Dialect. Apparently the reason we get away with it is that on the Db2 instance we test with, the non-N types support Unicode.

But if that's what we're going to rely on, we should have just chosen NationalizationSupport.IMPLICIT. And I'm really not sure that the non-N types support Unicode in every version/installation of Db2.

So this is a bug and we need to get it sorted out.

gavinking avatar Jun 28 '24 19:06 gavinking

See https://hibernate.atlassian.net/browse/HHH-18314. We need to start by figuring out the elegant/simple way to fix that one.

gavinking avatar Jun 28 '24 20:06 gavinking

My tests with Informix did not report an error even with the DB2 solution, I just noticed this schema. Maybe the test would throw an error correctly if it tried to set a value that cannot be stored in the basic char/varchar/longvarchar type. In the mentioned test from the JIRA issue, the value is set to product.setWarranty("My product warranty");, which even a varchar column has no problem with. However, I am currently unable to simulate such a case for the Informix default code set en_us.819. When trying to store the Euro symbol € I get an error even with the nvarchar column and my solution.

21:14:52,751  WARN SqlExceptionHelper:145 - SQL Error: -23103, SQLState: IX000
21:14:52,751 ERROR SqlExceptionHelper:150 - Code-set conversion function failed due to illegal sequence or invalid value.

VladoKuruc avatar Jun 28 '24 21:06 VladoKuruc

After the previous commit - (database in utf8) - the reported issue with special characters also works now. My guess that nvarchar can contain special characters compared to varchar was therefore wrong. The only difference is in the order of results according to national rules.

VladoKuruc avatar Jul 02 '24 07:07 VladoKuruc

@VladoKuruc If the only difference between CHAR and NCHAR on Informix is in the default collation order, perhaps the best option is to just define InformixDialect with NationalizationSupport.IMPLICIT. WDYT?

gavinking avatar Jul 02 '24 09:07 gavinking

I think we should explicitly map to NCHAR / NVARCHAR / LONGNVARCHAR columns, because I don't know if we would achieve the collation order otherwise.

The solution might not be child JdbcType classes as it is in this pull request, but rather test for the dialect method isImplementedNString (I don't dare to come up with a name ;) ) with a default value of true and an InformixDialect override to false. In that case, setNString / setString and getNString / getString would be called.

By the way, I don't think the org.hibernate.orm.test.mapping.converted.converter.AndNationalizedTests test needs to be omitted for DB2 either (I haven't tried it).

VladoKuruc avatar Jul 02 '24 09:07 VladoKuruc

The solution might not be child JdbcType classes as it is in this pull request, but rather test for the dialect method isImplementedNString (I don't dare to come up with a name ;) ) with a default value of true and an InformixDialect override to false. In that case, setNString / setString and getNString / getString would be called.

Yes, that was going to be my next suggestion. The JdbcTypes have access to the Dialect via WrapperOptions, and that's the way we're handling similar problems.

gavinking avatar Jul 02 '24 11:07 gavinking

The test org.hibernate.orm.test.nationalized.MaterializedNClobBindTest fails with the error "Cannot invoke org.hibernate.engine.spi.SharedSessionContractImplementor.getJdbcServices() because the return value of org.hibernate.type.descriptor.WrapperOptions.getSession() is null."

This happens because the test uses a private class MockWrapperOptions that implements WrapperOptions but intentionally returns null from its getSession() method. Can you help me, how to get a session into the that test?

VladoKuruc avatar Jul 02 '24 14:07 VladoKuruc

Thanks for your pull request!

This pull request appears to follow the contribution rules.

› This message was automatically generated.

@gavinking The pipeline https://ci.hibernate.org/job/hibernate-orm-pipeline/job/PR-8611/7/pipeline-console/?selected-node=4 is still waiting for user input. This might be because I changed the pull request from branch 6.5 to main. I'm not sure how to proceed in this case, whether a new pull request needs to be created.

VladoKuruc avatar Jul 03 '24 05:07 VladoKuruc

I'm not sure how to proceed in this case

I have no idea. Maybe try pushing again.

gavinking avatar Jul 03 '24 07:07 gavinking