Richard Zowalla created OPENJPA-3014:
----------------------------------------

             Summary: A named @SequenceGenerator fails where the database has 
no sequences
                 Key: OPENJPA-3014
                 URL: https://issues.apache.org/jira/browse/OPENJPA-3014
             Project: OpenJPA
          Issue Type: Bug
          Components: jpa
            Reporter: Richard Zowalla


A named @SequenceGenerator fails on any database whose dictionary has no 
nextSequenceQuery, for example MySQL:

  org.apache.openjpa.persistence.ArgumentException: Error instantiating named 
sequence "SEQGENERATOR": Your database dictionary does not support native 
sequences.
      at 
org.apache.openjpa.jdbc.kernel.NativeJDBCSeq.endConfiguration(NativeJDBCSeq.java:190)

Found by Maxim Solodovnik while running the TCK against MySQL.

Cause: AnnotationPersistenceMetaDataParser sets the plugin of a 
@SequenceGenerator to SequenceMetaData.IMPL_NATIVE unless the sequenceName is 
itself a plugin string, and JDBCSeqValue maps that alias to NativeJDBCSeq, 
which refuses to configure when dict.nextSequenceQuery is null. The 
openjpa.Sequence setting does not help: SequenceMetaData.instantiate() consults 
the configured system sequence only for the system sequence name, so a named 
generator always takes the plugin path. No configuration property can therefore 
avoid the failure.

Two independent parts.

1. Fall back to a table backed sequence where the database has none. OpenJPA 
already ships SequenceMapping.IMPL_TABLE and IMPL_VALUE_TABLE (TableJDBCSeq, 
ValueTableJDBCSeq), which keep the current value in a row of a sequence table 
and update it in place, the same approach other providers take on MySQL. A 
named generator resolved against a dictionary without nextSequenceQuery should 
use that instead of failing, with a warning, gated on nextSequenceQuery being 
null rather than on a dictionary class so every such dictionary benefits. The 
substitution belongs where the sequence is resolved (SequenceMapping / 
MappingRepository) so the runtime and the mapping tool behave the same; a patch 
that only changes MappingTool.addSequenceComponents fixes the tool and leaves a 
plain EntityManagerFactory failing, besides relying on a mutation of shared 
metadata.

Two details to decide: IMPL_TABLE keys its rows per class, so entities sharing 
one generator would get independent counters, whereas IMPL_VALUE_TABLE keys by 
sequence name and matches @SequenceGenerator semantics more closely; and 
initialValue and allocationSize travel on the SequenceMetaData rather than in 
the plugin string, so they must survive the substitution.

2. Use the real thing on MariaDB. MariaDB 10.3 and later has sequence objects 
(CREATE SEQUENCE, NEXT VALUE FOR, NEXTVAL()), so 
MariaDBDictionary.connectedConfiguration() should set nextSequenceQuery when 
the server reports 10.3 or later, in the version gated manner 
PostgresDictionary already uses for storeCharsAsNumbers, and leave older 
servers on the fallback from part 1.

Note for the TCK: its setup method issues CREATE SEQUENCE SEQGENERATOR START 
WITH 10 through a native query and logs the failure on MySQL. That logged error 
is expected there and harmless; what matters is that identifiers can still be 
allocated afterwards, which part 1 provides. On MariaDB the statement succeeds, 
which part 2 then uses.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to