hibernate-orm
hibernate-orm copied to clipboard
HHH-18312 Fix for Informix nationalized JDBC types support
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
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.
See https://hibernate.atlassian.net/browse/HHH-18314. We need to start by figuring out the elegant/simple way to fix that one.
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.
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 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?
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).
The solution might not be child
JdbcTypeclasses as it is in this pull request, but rather test for the dialect methodisImplementedNString(I don't dare to come up with a name ;) ) with a default value of true and anInformixDialectoverride to false. In that case,setNString/setStringandgetNString/getStringwould 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.
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?
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.
I'm not sure how to proceed in this case
I have no idea. Maybe try pushing again.