diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
index 7ab5207b0..d8912c73a 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
@@ -637,6 +637,13 @@ private ClassMetaData parseClassAnnotations() {
break;
case ID_CLASS:
if (isMetaDataMode()) {
+ // Jakarta Persistence 3.2 (section 2.4.1) no longer requires
+ // the primary key class to be public or to implement
+ // Serializable, so neither is validated here; see
+ // OPENJPA-2940 and OPENJPA-2984. A non-serializable id
+ // class does still prevent serializing the identity
+ // object it is wrapped in, which detached entities,
+ // remote commit events and a distributed data cache do.
meta.setObjectIdType(((IdClass) anno).value(), true);
}
break;
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
index 432f4d07b..c84a24b90 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
@@ -81,7 +81,6 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
@@ -1347,6 +1346,12 @@ protected boolean startIdClass(Attributes attrs)
} catch (Throwable t) {
throw getException(_loc.get("invalid-id-class", meta, cls), t);
}
+ // Jakarta Persistence 3.2 (section 2.4.1) no longer requires the primary
+ // key class to be public or to implement Serializable, so neither is
+ // validated here; see OPENJPA-2940 and OPENJPA-2984. A non-serializable
+ // id class does still prevent serializing the identity object it is
+ // wrapped in, which detached entities, remote commit events and a
+ // distributed data cache do.
meta.setObjectIdType(idCls, true);
return true;
}
diff --git a/openjpa-project/src/doc/manual/jpa_overview_pc.xml b/openjpa-project/src/doc/manual/jpa_overview_pc.xml
index a34392f1b..9fe864a88 100644
--- a/openjpa-project/src/doc/manual/jpa_overview_pc.xml
+++ b/openjpa-project/src/doc/manual/jpa_overview_pc.xml
@@ -838,17 +838,7 @@ following criteria:
-The class must be public.
-
-
-
-
-The class must be serializable.
-
-
-
-
-The class must have a public no-args constructor.
+The class must have a no-args constructor.
@@ -881,6 +871,19 @@ hierarchy mirrors the inheritance hierarchy of the owning entity classes (see
+Jakarta Persistence 3.2 no longer requires the identity class to be public or to
+implement java.io.Serializable, and OpenJPA no longer
+enforces either. An identity class that does not implement
+Serializable can, however, not be used where OpenJPA has
+to serialize the identity object it is wrapped in: serializing a detached
+entity, remote commit events in a clustered configuration, and a distributed
+data cache. Those fail with a
+java.io.NotSerializableException naming the identity
+class.
+
+
+
+
Though you may still create identity classes by hand, OpenJPA provides the
appidtool to automatically generate proper identity
classes based on your identity fields. See