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