OPENJPA-2940 - Jakarta Persistence 3.2 #142
Conversation
* Updated tentative version to 4.2.0-SNAPSHOT * Updated java version to 17
* Updating project to exclude almost all java.security deprecated calls * Passes default profile tests, but fails with postgres * Fixed some non-deterministic tests that fail with postgresql
* Tested and passed XML support using postgresql-17 as target db
* Replacing string number constructors * Removing dangling SecurityContext references
* removed TestSecurityContext because it is terminally deprecated since 17 and already removed in current JDK versions * updated h2-2 test profile jdbc url to remove strict definition * updated openjpa-slice and openjpa-xmlstore pom system variables definitions * updated GH actions workflows to use test-h2-2 profiles
* Project passes tests on derby, h2-2, postgres:latest, mysql:lts, mariadb:lts
* Updated dependency version * Added API new methods to API implementation classes with methods that throw UnsupportedOperationException, except for four methods in EntityManagerImpl that required proper implementations to pass tests * Project is still passing tests on derby and postgresql, at least
* Added XML JPA 3.2 schema and definitions * Added configuration support by 3.2 version * Added SchemaManager impl and corresponding methods in BrokerFactory interface * Added concrete working (not for h2-2) implementation of SchemaManager methods for JDBCBrokerFactory * Added concrete working impl for EMF#getName()
* Reverting unnecessary changes * Fixing broken map synchronization
* Changing signature of BrokerFactory API on schema dealing validate method * Adding test to check if validate operation throws exception when it fails * Changing GH CI workflow to allow usage of both self-hosted and GH hosted runners * Tested on derby, h2-2, postgresql:latest, mysql:lts, mariadb:lts
* Implementing emf creation passing PersistenceConfiguration
* Removing unused import in BrokerImpl * Implemented new PersistenceUnitUtil load methods
* Moved PUU loading tests to test unit already present * Updated test unit to junit 4.x format
…aming, and shared entity/collection table handling
Three fixes for JPA 3.2 TCK mapkeyenumerated/mapkeytemporal compliance (10→4 errors):
1. PersistenceMetaDataDefaults: When populateFromPCRegistry resolves field
members, a @transient field with an access-defining annotation on the
getter (e.g. @ElementCollection) now correctly returns the getter as the
backing member with MIXED|EXPLICIT access, matching the behavior of
populateFromReflection.
2. Map key column naming (JPA 3.2 spec 11.1.35): Default map key column
name changed from "key" (which triggered reserved-word suffix "KEY0")
to "<fieldName>_KEY". Applied to HandlerHandlerMapTableFieldStrategy,
HandlerRelationMapTableFieldStrategy, and
RelationRelationMapTableFieldStrategy.
3. Shared entity/collection table: When a @CollectionTable maps to the
same table as an entity @table (TCK pattern: Employee4 entity and
Department4 element collection both use EMP_MAPKEYCOL2), skip element
collection insert/update/delete to avoid PK conflicts with existing
entity rows. Detection is lazy to ensure all class mappings are loaded.
4. MappingTool: Enable FK constraint processing for drop scripts,
matching the existing behavior for create scripts.
…dentity When @mapsid("empPK") links an embedded ID field to a @manytoone relationship, the FK column name must follow the JPA default convention (relationship field name + "_" + referenced PK column name), not the embedded ID field name. OpenJPA was using "empPK" as the column name instead of "EMP_ID", causing NOT NULL constraint violations when the TCK DDL pre-creates the table with the spec-compliant column name. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… scripts The @foreignkey annotation on @SecondaryTable was parsed correctly but the named FK constraint was not appearing in generated DDL scripts. Three coordinated issues: 1. ForeignKey.isLogical() treated ALL named FKs as physical, causing runtime SynchronizeMappings to execute ALTER TABLE ADD CONSTRAINT against non-existent tables. Fix: isLogical() now only checks deleteAction, not the FK name. 2. SchemaTool.drop()/buildSchema() skipped logical FKs even in script generation mode. Fix: include named logical FKs when writing to a script (_writer != null), and always generate FK drops from metadata in script mode regardless of database state. 3. MappingTool.record() applied flags.sqlWriter (null by default) AFTER script-target writers, overwriting them. Fix: apply flags BEFORE script-target writers so they take precedence. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…identity (JPA 2.4.1.3 ex2b) Fix the last remaining JPA 3.2 TCK failure: derivedid ex2b, where an @EmbeddedId contains a field whose type is a plain @IdClass POJO (not @embeddable). This is the JPA spec 2.4.1.3 example 2b pattern. The fix spans six areas: - MappingRepository: return NoneFieldStrategy for non-@embeddable @IdClass fields inside @EmbeddedId that have @mapsid columns, preventing BLOB serialization while keeping the field MANAGE_PERSISTENT. - EmbedValueHandler: include @mapsid FK columns (with proper types from the target entity PK) in the @EmbeddedId column set for identity operations. Use reflection to convert between the @IdClass POJO and FK column values in toDataStoreValue1/toObjectValue1. - AbstractExpressionBuilder: resolve JPQL paths like d.id.empPK.firstName through the @manytoone @mapsid target entity when the @IdClass field has no type metadata. - AnnotationPersistenceMappingParser: mark @mapsid target fields as explicit so ClassMetaData.resolveMeta() does not demote them to MANAGE_NONE. - ClassRedefiner: catch VerifyError (Throwable, not just Exception) during redefineClasses and fall back to subclass-based enhancement. - PCClassFileTransformer: return null on error during retransformation so the ClassRedefiner temporary transformer can apply correct bytecode. TCK result: 2134 tests, 0 errors, 0 failures (was 1 error). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Drop Derby support from run-tck32.sh and make PostgreSQL the default with settings matching docker-compose.yml. Add prerequisite command checks and a README documenting the full TCK workflow. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove obsolete tck-profile (JPA 1.0b), tck2-profile (JPA 2.0), and test-db2-jcc profiles. Only the JPA 3.2 TCK profile remains.
- TestEdit: catch IllegalArgumentException (JPA 3.2 createQuery behavior) - TestMultiselect: verify nested compound selections throw IAE (JPA 6.9.1) - TestBulkJPQLAndDataCache: bulk DELETE does not cascade (JPA 4.10) - TestEJBDeleteUpdateImpl: clear persistence context after bulk DELETE - TestEJBQLFunction: fix Long vs Integer assertion type mismatch Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…table entities When entities share a table and FK column but only one participates in a bidirectional map, the map field may not be initialized on the related entity. Add null check before accessing the map. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…table The mappedBy key-column write logic in insert() was intended for @onetomany(mappedBy) but also fired for @manytomany(mappedBy), causing ArrayIndexOutOfBoundsException when join table columns were applied to the value entity's table. Skip key-column writes for ManyToMany since the owning side manages the join table. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Skip PK type validation for OpenJPAId instances (IntId, LongId, etc.) since they are already valid internal identity values. Also fix TestToOneLazyXmlOverride which passed Long to find() for an int PK. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Block java.sql.Date -> Time and java.sql.Date -> Timestamp in Filters.canConvert(), matching the existing blocks for java.util.Date. Update TimeKeeper test entity to use java.sql.Date field type (JPA 3.2 maps it to SQL DATE natively, no deprecated @TeMPOraL needed). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tSchemaGeneration The static _droppedTables set was unconditionally tracking tables dropped by schema gen scripts, preventing buildSchema/add from re-creating them. This caused cross-test contamination in unit tests where separate EMFs share the same JVM. Gate the tracking on SpecCompliantSchemaGeneration (TCK mode only) and remove redundant mapSchemaGenerationToSynchronize- Mappings call in 3-arg synchronizeMappings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…Generation The JPA spec default FK naming convention for @mapsid (relationship field + "_" + referenced PK column) breaks backward compatibility for existing databases using OpenJPA's original naming. Gate the renaming on SpecCompliantSchemaGeneration so existing users are not affected. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… 3.2) JPA 3.2 requires getResultList() to return a mutable List. OpenJPA now wraps ResultList in ArrayList, so iterators remain valid after query close and ResultList-specific APIs are no longer directly accessible. - TestQueryResults: iterators stay valid after close (expected behavior) - TestExternalizedParameter: verify queries execute without relying on ResultList.getUserObject() internal API Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ameters When stored procedure parameters are registered by name only, getOutputParameterValue(int) should accept 1-based positions corresponding to the declaration order, not reject them as invalid. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… attributes getId() and getDeclaredId() used pick() which returns only the first ID attribute. For IdClass entities with multiple IDs, this fails when the first attribute doesn't match the requested type. Iterate all ID attributes and match by type instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The try/catch for IOException in parseResources() was swallowing XML validation errors (SAXException wrapped in IOException), causing MissingResourceException instead of the expected GeneralException for invalid persistence.xml files. Re-throw when the cause is SAXException while still skipping actual I/O errors (corrupt jars). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Filter static enhancer fields in determineImplicitAccessType() so callback-only @MappedSuperclass correctly returns EMPTY access, preventing superclass compat check from overriding subclass PROPERTY - Update TestBiDirectionalJoinTable for JPA 3.2 spec 4.10: bulk DELETE does not cascade to related entities - Fix CompareByExample to recurse into ManagedType attributes (both associations and embeddables) after isAssociation() was corrected to exclude embeddable types Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update TestFieldAccessWithNonStandardAccessors: getdescription() is a valid property accessor per JPA 3.2 TCK, so description IS persistent - Remove SpecCompliantSchemaGeneration gate from SchemaTool dropped-table tracking; use remove() instead of contains() to prevent cross-test contamination while preserving drop-then-rebuild semantics Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…and MetaDataDefaults - Extract addSemicolonDelimited() in JDBCBrokerFactory to consolidate two identical type-list parsing loops - Extract getInstanceFields() in EmbedValueHandler to share non-static field iteration between toDataStoreValue1 and toObjectValue1 - Extract toPropertyName() in PersistenceMetaDataDefaults to replace four copies of getter-to-field name conversion logic Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Regarding the CI failure: will have a look tomorrow - I didnt use the h2 profile (as its done for PRs) locally. |
…sts from TestIdTypeFixes These tests duplicated coverage already provided by TestBigDecimalIdSharedTable and used fractional BigDecimal IDs that fail on H2 due to shared-column type resolution. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Hi, @rzo1 ! Great work! I've started to test the PR on different DBs. I got some errors (127) and failures (4) on a docker postgresql-18. I will rebuild everything using C locale to be on the safe side and test on MariaDB (LTS and latest), MySQL (LTS and latest). As soon as I have some results, I'll cycle back. |
Great - I expected failures (of the regular build) against various dbms. Do you run those tests with containers? If so - once you have some more results - I can run that as well locally. |
Yes, running in containers (official image of each db), dropping and recreating openjpa testing database in each run, building and testing openjpa also in container (temurin-21) with C locale. |
|
Yeah - feel free. I am sure, we can get it to work :) |
|
thanks @rzo1 - thats a huge and nice contribution! |
Hi all, @solomax, @cristof, all
This PR builds on @cristof's JPA 3.2 work, completed with the assistance of generative AI (Claude).
It fully passes the JPA 3.2 TCK (at least on PostgreSQL).
Tests run on Java 21, though there are some local failures - similar to what I see on master, likely an OSX or Java 21 issue rather than something introduced here:
The PR is fairly large, so feel free to cherry-pick whatever is useful. I expect there are concerns and things to address before this is merge-ready.
A number of new tests have been added that mirror TCK behavior. Happy to drop those if they're unwanted.
That said, it was a fun three-week experiment :)