On Tue, 13 Oct 2026 at 13:51, Richard Zowalla <[email protected]> wrote: > > Hi Maxim, > > The substitution is the right idea, but I would not put it in MappingTool. > > addSequenceComponents only runs during schema tooling. It works at runtime > only because it mutates the shared SequenceMetaData, so the rewritten plugin > happens to stick if the same repository is used afterwards. > Without the tool — a plain EMF against an existing schema — a named > @SequenceGenerator still reaches NativeJDBCSeq and fails with the same > message. > Rewriting metadata as a side effect of tooling also assumes the tool's > dictionary is the runtime's. > > Imho it belongs where the sequence is resolved, i.e. SequenceMapping / > MappingRepository. Then both the tool and the runtime see it and MappingTool > needs no change. > > I can sketch up an implementation under OPENJPA-3001 too, if you would prefer > that way
yes please :) you can use to the `tck-mysql` branch or create the new one :) > > Gruß > Richard > > > Am 12.10.2026 um 07:10 schrieb Maxim Solodovnik <[email protected]>: > > > > I've modified MappingTool as follows [1] > > Do you feel it worth committing? :) > > > > so tests still failing due to there are methods like this: > > > > protected void createSequenceGenerator() { > > try { > > getEntityTransaction().begin(); > > getEntityManager().createNativeQuery("CREATE SEQUENCE > > SEQGENERATOR START WITH 10").executeUpdate(); > > getEntityTransaction().commit(); > > } catch (Exception e) { > > logger.log(Logger.Level.ERROR, "Exception encountered while > > creating seq:", e); > > } > > } > > > > not sure how it should work .... > > > > [1] > > diff --git > > a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingTool.java > > b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingTool.java > > index 91c769ade..aeff3bf62 100644 > > --- > > a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingTool.java > > +++ > > b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingTool.java > > @@ -738,30 +738,39 @@ public class MappingTool > > SchemaGroup group) { > > SequenceMetaData smd = mapping.getIdentitySequenceMetaData(); > > Seq seq = null; > > - if (smd != null) > > + if (smd != null) { > > seq = smd.getInstance(null); > > - else if (mapping.getIdentityStrategy() == ValueStrategies.NATIVE > > + } else if (mapping.getIdentityStrategy() == ValueStrategies.NATIVE > > || (mapping.getIdentityStrategy() == ValueStrategies.NONE > > && mapping.getIdentityType() == ClassMetaData.ID_DATASTORE)) > > + { > > seq = _conf.getSequenceInstance(); > > + } > > > > - if (seq instanceof JDBCSeq) > > - ((JDBCSeq) seq).addSchema(mapping, group); > > + if (seq instanceof JDBCSeq jdbcSeq) { > > + jdbcSeq.addSchema(mapping, group); > > + } > > > > FieldMapping[] fmds; > > - if (mapping.getEmbeddingMetaData() == null) > > + if (mapping.getEmbeddingMetaData() == null) { > > fmds = mapping.getDefinedFieldMappings(); > > - else > > + } else { > > fmds = mapping.getFieldMappings(); > > + } > > for (FieldMapping fmd : fmds) { > > smd = fmd.getValueSequenceMetaData(); > > if (smd != null) { > > + if > > (SequenceMetaData.IMPL_NATIVE.equals(smd.getSequencePlugin()) && > > _dict.nextSequenceQuery == null) { > > + _log.warn(_loc.get("no-seq-sql", smd.getSequence())); > > + smd.setSequencePlugin(SequenceMapping.IMPL_TABLE); > > + } > > seq = smd.getInstance(_loader); > > - if (seq instanceof JDBCSeq) > > - ((JDBCSeq) seq).addSchema(mapping, group); > > - } > > - else if (fmd.getEmbeddedMapping() != null) > > + if (seq instanceof JDBCSeq jdbcSeq) { > > + jdbcSeq.addSchema(mapping, group); > > + } > > + } else if (fmd.getEmbeddedMapping() != null) { > > addSequenceComponents(fmd.getEmbeddedMapping(), group); > > + } > > } > > } > > > > > > On Fri, 9 Oct 2026 at 16:09, Maxim Solodovnik <[email protected]> wrote: > >> > >> Hello Richard, > >> > >> On Fri, 9 Oct 2026 at 14:58, Richard Zowalla <[email protected]> wrote: > >>> > >>> Hi Maxim, > >>> > >>> Good news: no emulation needed, and no growing table either. > >>> > >>> Neither MySQLDictionary nor MariaDBDictionary sets nextSequenceQuery, so > >>> NativeJDBCSeq.endConfiguration() throws for any @SequenceGenerator. But > >>> OpenJPA already ships a table-backed sequence: SequenceMapping.IMPL_TABLE > >>> / IMPL_VALUE_TABLE, implemented by TableJDBCSeq, which keeps a single row > >>> per sequence in OPENJPA_SEQUENCE_TABLE (column SEQUENCE_VALUE) and > >>> updates it in place. That is the same approach Hibernate and EclipseLink > >>> take on MySQL, so AUTO_INCREMENT is not required and nothing grows. > >>> > >>> I would split it in two, because the two dbms are different: > >>> > >>> MariaDB can do it natively. MariaDB 10.3 and later has real sequence > >>> objects (CREATE SEQUENCE, NEXT VALUE FOR seq, NEXTVAL(seq)), and you are > >>> running 11.8. So MariaDBDictionary.connectedConfiguration() can set > >>> nextSequenceQuery once the server reports >= 10.3, following the > >>> version-gated pattern PostgresDictionary already uses for > >>> storeCharsAsNumbers, and leave the older versions alone. That should make > >>> the sequence TCK tests pass on MariaDB without any mapping change. > >>> > >>> MySQL has no sequences at any version, so a @SequenceGenerator has to > >>> fall back to the table sequence. Interestingly part of it is already > >>> there: AnnotationPersistenceMetaDataParser does both GenerationType.TABLE > >>> and GenerationType.SEQUENCE through the system openjpa.Sequence setting > >>> when the generator is unnamed. The gap would be a named generator on a > >>> dictionary without native sequences, which currently fails instead of > >>> falling back. > >>> > >>> As a workaround for your branch right now, before any code change, you > >>> can point the named generator at the table implementation, e.g. > >>> > >>> openjpa.Sequence: table(Table=OPENJPA_SEQUENCE_TABLE) > >> > >> this would be hard to implement for TCK :( > >> we do pass params via > >> <jpa.provider.implementation.specific.properties> which has `:` > >> delimiter > >> but inside the key it has `=` delimiter :( > >> > >> and we already passing `openjpa.Sequence=time` .... > >> > >> so the only options are: System property and code modification :) > >> I'll try to modify the code > >> > >>> > >>> for the unnamed case, or give the generator an explicit table > >>> implementation in the mapping. > >>> > >>> The MariaDB version check would be low risk, the MySQL fallback changes > >>> identity generation behaviour on a database people are using, so I would > >>> keep them as separate commits (and probably separate review) even if they > >>> share one issue. > >>> > >>> Hope it helps > >>> Richard > >>> > >>> > >>>> Am 09.10.2026 um 05:45 schrieb Maxim Solodovnik <[email protected]>: > >>>> > >>>> There is great progress :)) > >>>> Failing list is reduced :)) > >>>> > >>>> Some tests are failing due to: > >>>> > >>>> ``` > >>>> SEVERE: Exception encountered while creating seq: > >>>> <openjpa-4.2.0-SNAPSHOT-r832b5cdM fatal user error> > >>>> org.apache.openjpa.persistence.ArgumentException: Error instantiating > >>>> named sequence "SEQGENERATOR": Your database dictionary does not > >>>> support native sequences. To tell the dictionary how to select > >>>> sequence values, use: > >>>> openjpa.jdbc.DBDictionary: NextSequenceQuery="SELECT NEXT VALUE FOR > >>>> "SEQGENERATOR" > >>>> Where the above string is replaced with the proper SQL for your database. > >>>> at > >>>> org.apache.openjpa.jdbc.kernel.NativeJDBCSeq.endConfiguration(NativeJDBCSeq.java:190) > >>>> ``` > >>>> > >>>> I guess SEQUENCE can be emulated with AUTOINCREMENT > >>>> https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html > >>>> But having growing table seems to be overkill .... > >>>> > >>>> On Thu, 8 Oct 2026 at 21:08, Maxim Solodovnik <[email protected]> > >>>> wrote: > >>>>> > >>>>> It seems regular MySql tests are broken :( > >>>>> > >>>>> ``` > >>>>> [ERROR] Failures: > >>>>> [ERROR] > >>>>> TestContainerSpecCompatibilityOptions>AbstractPersistenceTestCase.run:213->AbstractPersistenceTestCase.runBare:553->AbstractPersistenceTestCase.runBare:577->AbstractPersistenceTestCase.runTest:590->testLegacyDefaultMapKeyColumnName:471->assertSQLFragnments:932 > >>>>> None of the following 3 SQL > >>>>> [ERROR] > >>>>> TestBiDirectionalJoinTable>AbstractPersistenceTestCase.run:213->AbstractPersistenceTestCase.runBare:553->AbstractPersistenceTestCase.runBare:577->AbstractPersistenceTestCase.runTest:590->testBulkDelete:138->SQLListenerTestCase.assertSQL:74 > >>>>> Expected regular expression > >>>>> [ERROR] > >>>>> TestBulkDeleteCompositeId>AbstractPersistenceTestCase.run:213->AbstractPersistenceTestCase.runBare:553->AbstractPersistenceTestCase.runBare:577->AbstractPersistenceTestCase.runTest:590->testCompositeKeyCandidateWithoutCriteria:65->SQLListenerTestCase.assertSQL:74 > >>>>> Expected regular expression > >>>>> [ERROR] > >>>>> TestBulkDeleteDependentFields>AbstractPersistenceTestCase.run:213->AbstractPersistenceTestCase.runBare:553->AbstractPersistenceTestCase.runBare:577->AbstractPersistenceTestCase.runTest:590->testUnfilteredDeleteCleansOwnedTablesOfDependentFields:140->SQLListenerTestCase.assertSQL:74 > >>>>> Expected regular > >>>>> [ERROR] > >>>>> TestBulkDeleteJoinTable>AbstractPersistenceTestCase.run:213->AbstractPersistenceTestCase.runBare:553->AbstractPersistenceTestCase.runBare:577->AbstractPersistenceTestCase.runTest:590->testBulkDeleteWithoutCriteriaEmptiesOwnedTables:58->SQLListenerTestCase.assertSQL:74 > >>>>> Expected regular expression > >>>>> [ERROR] > >>>>> TestBulkDeleteSubclassJoinTable>AbstractPersistenceTestCase.run:213->AbstractPersistenceTestCase.runBare:553->AbstractPersistenceTestCase.runBare:577->AbstractPersistenceTestCase.runTest:590->testBulkDeleteThroughBaseClass:51->SQLListenerTestCase.assertSQL:74 > >>>>> Expected regular expression > >>>>> > >>>>> [INFO] OpenJPA Persistence JDBC ........................... FAILURE [ > >>>>> 01:33 h] > >>>>> > >>>>> [ERROR] Tests run: 3761, Failures: 6, Errors: 0, Skipped: 0 > >>>>> ``` > >>>>> > >>>>> On Thu, 8 Oct 2026 at 13:37, Maxim Solodovnik <[email protected]> > >>>>> wrote: > >>>>>> > >>>>>> Hello Richard, > >>>>>> > >>>>>> On Thu, 8 Oct 2026 at 13:24, Richard Zowalla <[email protected]> wrote: > >>>>>>> > >>>>>>> Hi Maxim, > >>>>>>> > >>>>>>> the truncation is a consequence of it, not a separate problem. > >>>>>>> > >>>>>>> DBDictionary.storeCharsAsNumbers still defaults to true > >>>>>>> (DBDictionary:327), and only DB2 (DB2Dictionary:124) and PostgreSQL > >>>>>>> (PostgresDictionary:151) switch it off. > >>>>>>> MySQL inherits the legacy default, so: > >>>>>>> > >>>>>>> - getPreferredType() maps JavaTypes.CHAR to Types.INTEGER > >>>>>>> (DBDictionary:2006) — that is the "Given column: Type: integer" in > >>>>>>> your warning, and > >>>>>>> - setChar() takes the numeric branch because the mapped column > >>>>>>> reports as INTEGER-compatible (DBDictionary:1285) and does > >>>>>>> setInt(stmnt, idx, (int) val). > >>>>>>> > >>>>>>> So for > >>>>>>> > >>>>>>> @Column(name = "CHARDATA") > >>>>>>> protected char characterData; > >>>>>>> > >>>>>>> we send 65 into the TCK's CHARDATA CHAR column, and two digits do not > >>>>>>> fit one character: code 1406, "Data too long for column 'CHARDATA'". > >>>>>>> > >>>>>>> Workaround for your branch, no code change needed: > >>>>>>> > >>>>>>> openjpa.jdbc.DBDictionary=mysql(StoreCharsAsNumbers=false) > >>>>>>> > >>>>>>> However, I would fix it the way we did for PostgreSQL in > >>>>>>> OPENJPA-2971: have MySQLDictionary set storeCharsAsNumbers = false in > >>>>>>> the constructor, keep the isStoreCharsAsNumbersExplicit() > >>>>>>> so a value a user set explicitly is never overwritten, and add a > >>>>>>> migration note — existing MySQL schemas created by earlier OpenJPA > >>>>>>> releases have INTEGER columns for > >>>>>>> char fields and will need StoreCharsAsNumbers=true to keep working. > >>>>>> > >>>>>> I'll give it a try and will write back :) > >>>>>> Thanks a million for your help! :) > >>>>>> > >>>>>>> > >>>>>>> That is exactl OPENJPA-3001. > >>>>>>> > >>>>>>> On the schema generation: drop-and-create cannot help here, and the > >>>>>>> error you get comes from a different place. > >>>>>>> "Table ... has a foreign key to table ... that has not been > >>>>>>> generated" is thrown by SchemaGenerator:885 while reading the > >>>>>>> live database metadata; it fires when a foreign key in the existing > >>>>>>> schema points at a table that is not part of the group being > >>>>>>> generated. > >>>>>>> > >>>>>>> With leftover tables from other TCK persistence units in the same > >>>>>>> database, any subset run trips it. > >>>>>>> > >>>>>>> Since the TCK ships its own DDL, I would not let OpenJPA generate the > >>>>>>> schema for a TCK run at all. > >>>>>>> A clean database per run (DROP DATABASE / CREATE DATABASE, or a > >>>>>>> schema per PU) is more reliable > >>>>>>> than asking the schema tool to reconcile. Once the column type is > >>>>>>> right, the incompatibility warning and the truncation, should > >>>>>>> disappear. > >>>>>> > >>>>>> Actually current script drops all local data at docker stop > >>>>>> https://github.com/apache/openjpa/commit/db9c64be252643555803988f3330d8b32a09dd5a > >>>>>> ``` > >>>>>> <keepContainer>false</keepContainer> > >>>>>> <removeVolumes>true</removeVolumes> > >>>>>> ``` > >>>>>> > >>>>>>> > >>>>>>> Best regards, > >>>>>>> Richard > >>>>>>> > >>>>>>> On 2026-10-07 06:10 UTC Maxim Solodovnik wrote: > >>>>>>>> Hello All, > >>>>>>>> > >>>>>>>> I'm trying to investigate TCK failures with Mysql DB > >>>>>>>> > >>>>>>>> I'm investigating 'Data truncation: Data too long for column' class > >>>>>>>> of problems > >>>>>>>> I've notices these errors are coupled with warnings like: > >>>>>>>> ``` > >>>>>>>> 19 WARN [main] openjpa.jdbc.Schema - Existing column "CHARDATA" on > >>>>>>>> table "DATATYPES" is incompatible with the same column in the given > >>>>>>>> schema definition. Existing column: > >>>>>>>> Full Name: DATATYPES.CHARDATA > >>>>>>>> Type: char > >>>>>>>> Size: 1 > >>>>>>>> Default: null > >>>>>>>> Not Null: false > >>>>>>>> Given column: > >>>>>>>> Full Name: DATATYPES.CHARDATA > >>>>>>>> Type: integer > >>>>>>>> Size: 0 > >>>>>>>> Default: null > >>>>>>>> Not Null: false > >>>>>>>> ``` > >>>>>>>> > >>>>>>>> So my guess was: schemaTool need to be instructed to drop/create > >>>>>>>> existing table so column definition will be updated to have correct > >>>>>>>> type > >>>>>>>> > >>>>>>>> I've tried to add > >>>>>>>> `jakarta.persistence.schema-generation.database.action=drop-and-create` > >>>>>>>> (as well as > >>>>>>>> `:jakarta.persistence.schema-generation.database.action=drop-and-create:jakarta.persistence.schema-generation.scripts.action=drop-and-create`) > >>>>>>>> > >>>>>>>> But got `Table "{0}" has a foreign key to table "{1}" that has not > >>>>>>>> been \ > >>>>>>>> generated. You must run the schema generator on all inter-related > >>>>>>>> tables \ > >>>>>>>> at once.` errors instead :( > >>>>>>>> > >>>>>>>> Any help is appreciated :))) > >>>>>>>> > >>>>>>>> I'm playing at `tck-mysql` branch :)) > >>>>>>>> > >>>>>>>> > >>>>>>>> -- > >>>>>>>> Best regards, > >>>>>>>> Maxim > >>>>>>>> > >>>>>> > >>>>>> > >>>>>> > >>>>>> -- > >>>>>> Best regards, > >>>>>> Maxim > >>>>> > >>>>> > >>>>> > >>>>> -- > >>>>> Best regards, > >>>>> Maxim > >>>> > >>>> > >>>> > >>>> -- > >>>> Best regards, > >>>> Maxim > >>> > >> > >> > >> -- > >> Best regards, > >> Maxim > > > > > > > > -- > > Best regards, > > Maxim > -- Best regards, Maxim
