You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2026/06/14 19:28:03 UTC
(cayenne) branch past-M2 updated (b39a15ca8 -> a9ba83767)
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a change to branch past-M2
in repository https://gitbox.apache.org/repos/asf/cayenne.git
from b39a15ca8 flaky test, e.g. fails on Oracle
new 5ad7100cd CAY-2964 ClassCastException for non-generated meaningful PKs
new 074cd9eaf CAY-2964 ClassCastException for non-generated meaningful PKs
new a9ba83767 typos, cleanup
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
RELEASE-NOTES.txt | 1 +
.../crypto/transformer/bytes/CbcDecryptor.java | 2 +-
.../cayenne/dbsync/merge/token/MergerToken.java | 2 +-
.../java/org/apache/cayenne/access/ObjectDiff.java | 14 +++----
.../access/flush/PermanentObjectIdVisitor.java | 37 ++++++++++---------
.../org/apache/cayenne/dba/JdbcPkGenerator.java | 26 +++++++------
.../java/org/apache/cayenne/dba/PkGenerator.java | 18 +++++++--
.../dba/sqlserver/SQLServerPkGenerator.java | 4 +-
.../org/apache/cayenne/map/EntityResolver.java | 43 +++++++++++-----------
.../org/apache/cayenne/map/ObjRelationship.java | 6 +--
.../java/org/apache/cayenne/map/Relationship.java | 2 +-
.../org/apache/cayenne/reflect/ArcProperty.java | 2 +-
.../apache/cayenne/reflect/BaseArcProperty.java | 6 +--
.../DataContextEntityWithMeaningfulPKIT.java | 12 +++++-
.../apache/cayenne/access/DataContextExtrasIT.java | 2 +-
.../object-relational-mapping.adoc | 2 +-
16 files changed, 102 insertions(+), 77 deletions(-)
(cayenne) 03/03: typos, cleanup
Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch past-M2
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit a9ba8376701cb75da4b757b726c86bde193d26e6
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Jun 14 15:27:23 2026 -0400
typos, cleanup
---
.../crypto/transformer/bytes/CbcDecryptor.java | 2 +-
.../cayenne/dbsync/merge/token/MergerToken.java | 2 +-
.../java/org/apache/cayenne/access/ObjectDiff.java | 14 +++----
.../org/apache/cayenne/map/EntityResolver.java | 43 +++++++++++-----------
.../org/apache/cayenne/map/ObjRelationship.java | 6 +--
.../java/org/apache/cayenne/map/Relationship.java | 2 +-
.../org/apache/cayenne/reflect/ArcProperty.java | 2 +-
.../apache/cayenne/reflect/BaseArcProperty.java | 6 +--
.../object-relational-mapping.adoc | 2 +-
9 files changed, 39 insertions(+), 40 deletions(-)
diff --git a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcDecryptor.java b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcDecryptor.java
index 5cd2d8bdb..b0f4a972c 100644
--- a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcDecryptor.java
+++ b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcDecryptor.java
@@ -32,7 +32,7 @@ import org.apache.cayenne.crypto.CayenneCryptoException;
/**
* A {@link BytesDecryptor} that decrypts the provided bytes that were encrypted
- * by the complimentary {@link CbcEncryptor}. The object is stateful and is not
+ * by the complementary {@link CbcEncryptor}. The object is stateful and is not
* thread-safe.
*
* @since 4.0
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/MergerToken.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/MergerToken.java
index e6fd839a9..d52b66b7e 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/MergerToken.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/merge/token/MergerToken.java
@@ -41,7 +41,7 @@ public interface MergerToken extends Comparable<MergerToken> {
MergeDirection getDirection();
/**
- * Create a complimentary token with the reverse direction. AddColumn in one direction becomes
+ * Create a complementary token with the reverse direction. AddColumn in one direction becomes
* DropColumn in the other direction.
* <p>
* Not all tokens are reversible.
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/ObjectDiff.java b/cayenne/src/main/java/org/apache/cayenne/access/ObjectDiff.java
index d05939f63..1303b4e54 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/ObjectDiff.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/ObjectDiff.java
@@ -65,7 +65,7 @@ public class ObjectDiff extends NodeDiff {
private Map<ArcOperation, ArcOperation> flatIds;
private Map<ArcOperation, ArcOperation> phantomFks;
- private Persistent object;
+ private final Persistent object;
ObjectDiff(final Persistent object) {
@@ -244,11 +244,11 @@ public class ObjectDiff extends NodeDiff {
}
} else if (property.getComplimentaryReverseArc() == null) {
- // register complimentary arc diff
+ // register complementary arc diff
ArcId arc = arcId.getReverseId();
//new ArcId(ASTDbPath.DB_PREFIX + property.getComplimentaryReverseDbRelationshipPath(), property.getName());
- ArcOperation complimentaryOp = new ArcOperation(targetId, arcDiff.getNodeId(), arc, arcDiff.isDelete());
- parent.registerDiff(targetId, complimentaryOp);
+ ArcOperation complementaryOp = new ArcOperation(targetId, arcDiff.getNodeId(), arc, arcDiff.isDelete());
+ parent.registerDiff(targetId, complementaryOp);
}
} else if (property instanceof ToOneProperty) {
@@ -455,9 +455,9 @@ public class ObjectDiff extends NodeDiff {
static final class ArcOperation extends NodeDiff {
- private Object targetNodeId;
- private ArcId arcId;
- private boolean delete;
+ private final Object targetNodeId;
+ private final ArcId arcId;
+ private final boolean delete;
ArcOperation(Object nodeId, Object targetNodeId, ArcId arcId, boolean delete) {
diff --git a/cayenne/src/main/java/org/apache/cayenne/map/EntityResolver.java b/cayenne/src/main/java/org/apache/cayenne/map/EntityResolver.java
index c45e658ef..89edc83bf 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/EntityResolver.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/EntityResolver.java
@@ -19,22 +19,8 @@
package org.apache.cayenne.map;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-
import org.apache.cayenne.Persistent;
import org.apache.cayenne.access.types.ValueObjectTypeRegistry;
-
import org.apache.cayenne.annotation.PostAdd;
import org.apache.cayenne.annotation.PostLoad;
import org.apache.cayenne.annotation.PostPersist;
@@ -55,6 +41,18 @@ import org.apache.cayenne.reflect.valueholder.ValueHolderDescriptorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Represents a virtual shared namespace for zero or more DataMaps. Unlike
* DataMap, EntityResolver is intended to work as a runtime container of
@@ -67,10 +65,11 @@ import org.slf4j.LoggerFactory;
*/
public class EntityResolver implements MappingNamespace, Serializable {
- protected static final Logger logger = LoggerFactory.getLogger(EntityResolver.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(EntityResolver.class);
protected static AtomicLong incrementer = new AtomicLong();
protected static final Map<LifecycleEvent, Class<? extends Annotation>> LIFECYCLE_EVENT_MAP;
+
static {
LIFECYCLE_EVENT_MAP = new EnumMap<>(LifecycleEvent.class);
LIFECYCLE_EVENT_MAP.put(LifecycleEvent.POST_ADD, PostAdd.class);
@@ -152,8 +151,9 @@ public class EntityResolver implements MappingNamespace, Serializable {
reverse.setRuntime(true);
targetEntity.addRelationship(reverse);
- logger.info("added runtime complimentary DbRelationship from " + targetEntity.getName()
- + " to " + reverse.getTargetEntityName());
+ LOGGER.info("added complementary runtime DbRelationship from {} to {}",
+ targetEntity.getName(),
+ reverse.getTargetEntityName());
}
}
}
@@ -166,7 +166,7 @@ public class EntityResolver implements MappingNamespace, Serializable {
do {
name = "runtimeRelationship" + incrementer.getAndIncrement();
- } while(entity.getRelationship(name) != null);
+ } while (entity.getRelationship(name) != null);
return name;
}
@@ -185,7 +185,7 @@ public class EntityResolver implements MappingNamespace, Serializable {
// load annotated methods
for (Method m : entityClass.getDeclaredMethods()) {
LIFECYCLE_EVENT_MAP.forEach((eventType, annotationType) -> {
- if(m.getDeclaredAnnotation(annotationType) != null) {
+ if (m.getDeclaredAnnotation(annotationType) != null) {
callbackRegistry.addCallback(eventType, entityClass, m);
}
});
@@ -460,8 +460,7 @@ public class EntityResolver implements MappingNamespace, Serializable {
* ObjEntity that maps to the services the specified class
*
* @return the required ObjEntity or null if there is none that matches the
- * specifier
- *
+ * specifier
* @since 4.0
*/
public ObjEntity getObjEntity(Class<?> entityClass) {
@@ -492,7 +491,7 @@ public class EntityResolver implements MappingNamespace, Serializable {
/**
* Returns an object that compiles and stores {@link ClassDescriptor}
* instances for all entities.
- *
+ *
* @since 3.0
*/
public ClassDescriptorMap getClassDescriptorMap() {
diff --git a/cayenne/src/main/java/org/apache/cayenne/map/ObjRelationship.java b/cayenne/src/main/java/org/apache/cayenne/map/ObjRelationship.java
index 1de5d3eeb..24e34dd3b 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/ObjRelationship.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/ObjRelationship.java
@@ -160,7 +160,7 @@ public class ObjRelationship extends Relationship<ObjEntity, ObjAttribute, ObjRe
}
/**
- * Returns the name of a complimentary relationship going in the opposite
+ * Returns the name of a complementary relationship going in the opposite
* direction or null if it doesn't exist.
*
* @since 1.2
@@ -171,7 +171,7 @@ public class ObjRelationship extends Relationship<ObjEntity, ObjAttribute, ObjRe
}
/**
- * Returns a "complimentary" ObjRelationship going in the opposite
+ * Returns a "complementary" ObjRelationship going in the opposite
* direction. Returns null if no such relationship is found.
*/
@Override
@@ -226,7 +226,7 @@ public class ObjRelationship extends Relationship<ObjEntity, ObjAttribute, ObjRe
}
/**
- * Creates a complimentary reverse relationship from target entity to the
+ * Creates a complementary reverse relationship from target entity to the
* source entity. A new relationship is created regardless of whether one
* already exists. Returned relationship is not attached to the source
* entity and has no name. Throws a {@link CayenneRuntimeException} if
diff --git a/cayenne/src/main/java/org/apache/cayenne/map/Relationship.java b/cayenne/src/main/java/org/apache/cayenne/map/Relationship.java
index d705b13b5..ba961bfb6 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/Relationship.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/Relationship.java
@@ -177,7 +177,7 @@ public abstract class Relationship<E extends Entity<E, A, R>, A extends Attribut
}
/**
- * Returns a "complimentary" relationship going in the opposite direction. Returns
+ * Returns a "complementary" relationship going in the opposite direction. Returns
* null if no such relationship is found.
* @since 3.1
*/
diff --git a/cayenne/src/main/java/org/apache/cayenne/reflect/ArcProperty.java b/cayenne/src/main/java/org/apache/cayenne/reflect/ArcProperty.java
index 0bab4ca7d..1971ca533 100644
--- a/cayenne/src/main/java/org/apache/cayenne/reflect/ArcProperty.java
+++ b/cayenne/src/main/java/org/apache/cayenne/reflect/ArcProperty.java
@@ -45,7 +45,7 @@ public interface ArcProperty extends PropertyDescriptor {
String getComplimentaryReverseDbRelationshipPath();
/**
- * Returns a complimentary reverse ArcProperty or null if no reverse arc
+ * Returns a complementary reverse ArcProperty or null if no reverse arc
* exists.
*/
ArcProperty getComplimentaryReverseArc();
diff --git a/cayenne/src/main/java/org/apache/cayenne/reflect/BaseArcProperty.java b/cayenne/src/main/java/org/apache/cayenne/reflect/BaseArcProperty.java
index d864cf1f4..a11244d43 100644
--- a/cayenne/src/main/java/org/apache/cayenne/reflect/BaseArcProperty.java
+++ b/cayenne/src/main/java/org/apache/cayenne/reflect/BaseArcProperty.java
@@ -28,7 +28,7 @@ import org.apache.cayenne.map.ObjRelationship;
*/
public abstract class BaseArcProperty extends BaseProperty implements ArcProperty {
- protected String complimentaryReverseArcName;
+ protected String complementaryReverseArcName;
protected ClassDescriptor targetDescriptor;
protected ObjRelationship relationship;
protected CayennePath reverseDbPath;
@@ -39,7 +39,7 @@ public abstract class BaseArcProperty extends BaseProperty implements ArcPropert
super(owner, accessor);
this.targetDescriptor = targetDescriptor;
- this.complimentaryReverseArcName = reverseName;
+ this.complementaryReverseArcName = reverseName;
this.relationship = owner.getEntity().getRelationship(getName());
}
@@ -62,7 +62,7 @@ public abstract class BaseArcProperty extends BaseProperty implements ArcPropert
}
public ArcProperty getComplimentaryReverseArc() {
- return (ArcProperty) targetDescriptor.getProperty(complimentaryReverseArcName);
+ return (ArcProperty) targetDescriptor.getProperty(complementaryReverseArcName);
}
public ClassDescriptor getTargetDescriptor() {
diff --git a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/object-relational-mapping.adoc b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/object-relational-mapping.adoc
index 315659dbb..099ce5dfd 100644
--- a/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/object-relational-mapping.adoc
+++ b/docs/asciidoc/getting-started-guide/src/docs/asciidoc/_getting-started-guide/object-relational-mapping.adoc
@@ -71,7 +71,7 @@ image::modeler-dbrelationship.png[align="center"]
- Click "Done" to confirm the changes and close the dialog.
-- Two complimentary relationships have been created - from ARTIST to PAINTING
+- Two complementary relationships have been created - from ARTIST to PAINTING
and back.
- Repeat the steps above to create a many-to-one relationship from PAINTING to GALLERY, calling the relationships pair
(cayenne) 02/03: CAY-2964 ClassCastException for non-generated meaningful PKs
Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch past-M2
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 074cd9eaf1732191d05f75a2b525eb74947fcb66
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Jun 14 13:47:28 2026 -0400
CAY-2964 ClassCastException for non-generated meaningful PKs
---
RELEASE-NOTES.txt | 1 +
.../access/flush/PermanentObjectIdVisitor.java | 37 +++++++++++-----------
.../org/apache/cayenne/dba/JdbcPkGenerator.java | 26 ++++++++-------
.../java/org/apache/cayenne/dba/PkGenerator.java | 18 ++++++++---
.../dba/sqlserver/SQLServerPkGenerator.java | 4 +--
.../apache/cayenne/access/DataContextExtrasIT.java | 2 +-
6 files changed, 52 insertions(+), 36 deletions(-)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index cc06801ef..e381602f4 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -24,6 +24,7 @@ CAY-2958 Empty join is saved
CAY-2959 Modeler: DbRelationship dialog "Cancel" doesn't cancel
CAY-2960 Undoing renamed relationship change throws
CAY-2961 PostgreSQL "text" column is reverse-engineered as CLOB
+CAY-2964 ClassCastException for non-generated meaningful PKs
----------------------------------
Release: 5.0-M2
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/flush/PermanentObjectIdVisitor.java b/cayenne/src/main/java/org/apache/cayenne/access/flush/PermanentObjectIdVisitor.java
index d1412a6d9..a412db1c2 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/flush/PermanentObjectIdVisitor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/flush/PermanentObjectIdVisitor.java
@@ -19,8 +19,6 @@
package org.apache.cayenne.access.flush;
-import java.util.Map;
-
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.access.DataDomain;
@@ -37,6 +35,8 @@ import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.reflect.ClassDescriptor;
+import java.util.Map;
+
/**
* Visitor that fills replacement map of {@link ObjectId}s of inserted objects.
*
@@ -65,9 +65,9 @@ class PermanentObjectIdVisitor implements DbRowOpVisitor<Void> {
return null;
}
- if((lastObjEntity == null && lastDbEntity == null) || !id.getEntityName().equals(lastEntityName)) {
+ if ((lastObjEntity == null && lastDbEntity == null) || !id.getEntityName().equals(lastEntityName)) {
lastEntityName = id.getEntityName();
- if(lastEntityName.startsWith(ASTDbPath.DB_PREFIX)) {
+ if (lastEntityName.startsWith(ASTDbPath.DB_PREFIX)) {
lastDbEntity = resolver.getDbEntity(lastEntityName.substring(ASTDbPath.DB_PREFIX.length()));
lastObjEntity = null;
lastDescriptor = null;
@@ -87,7 +87,7 @@ class PermanentObjectIdVisitor implements DbRowOpVisitor<Void> {
@Override
public Void visitDelete(DeleteDbRowOp dbRow) {
// flattened ids will be temporary for delete operation, replace it
- if(dbRow.getChangeId().isTemporary() && dbRow.getChangeId().isReplacementIdAttached()) {
+ if (dbRow.getChangeId().isTemporary() && dbRow.getChangeId().isReplacementIdAttached()) {
dbRow.setChangeId(dbRow.getChangeId().createReplacementId());
}
return null;
@@ -110,18 +110,17 @@ class PermanentObjectIdVisitor implements DbRowOpVisitor<Void> {
continue;
}
+ ObjAttribute objAttr = lastObjEntity != null ? lastObjEntity.getAttributeForDbAttribute(dbAttr) : null;
+
// handle meaningful PK
- if(lastObjEntity != null) {
- ObjAttribute objAttr = lastObjEntity.getAttributeForDbAttribute(dbAttr);
- if (objAttr != null) {
- Object value = lastDescriptor.getProperty(objAttr.getName()).readPropertyDirectly(dbRow.getObject());
- if (value != null) {
- // primitive 0 has to be treated as NULL, or otherwise we can't generate PK for POJO's
- Class<?> javaClass = objAttr.getJavaClass();
- if (!javaClass.isPrimitive() || !(value instanceof Number number) || number.intValue() != 0) {
- idMap.put(dbAttrName, value);
- continue;
- }
+ if (objAttr != null) {
+ Object value = lastDescriptor.getProperty(objAttr.getName()).readPropertyDirectly(dbRow.getObject());
+ if (value != null) {
+ // primitive 0 has to be treated as NULL, or otherwise we can't generate PK for POJO's
+ Class<?> javaClass = objAttr.getJavaClass();
+ if (!javaClass.isPrimitive() || !(value instanceof Number number) || number.intValue() != 0) {
+ idMap.put(dbAttrName, value);
+ continue;
}
}
}
@@ -140,11 +139,13 @@ class PermanentObjectIdVisitor implements DbRowOpVisitor<Void> {
// finally, use database generation mechanism
try {
- Object pkValue = pkGenerator.generatePk(lastNode, dbAttr);
+ Class<?> javaType = objAttr != null ? objAttr.getJavaClass() : null;
+
+ Object pkValue = pkGenerator.generatePk(lastNode, dbAttr, javaType);
idMap.put(dbAttrName, pkValue);
autoPkDone = true;
} catch (Exception ex) {
- throw new CayenneRuntimeException("Error generating PK: %s", ex, ex.getMessage());
+ throw new CayenneRuntimeException("Error generating PK: %s", ex, ex.getMessage());
}
}
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java b/cayenne/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
index 6423370ef..9e15df372 100644
--- a/cayenne/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
+++ b/cayenne/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
@@ -25,6 +25,8 @@ import org.apache.cayenne.ObjectId;
import org.apache.cayenne.ResultIterator;
import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.access.OperationObserver;
+import org.apache.cayenne.access.types.ValueObjectType;
+import org.apache.cayenne.access.types.ValueObjectTypeRegistry;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbKeyGenerator;
@@ -185,17 +187,8 @@ public class JdbcPkGenerator implements PkGenerator {
}
}
- /**
- * Generates a unique and non-repeating primary key for specified dbEntity.
- * <p>
- * This implementation is naive since it does not lock the database rows
- * when executing select and subsequent update. Adapter-specific
- * implementations are more robust.
- * </p>
- *
- * @since 3.0
- */
- public Object generatePk(DataNode node, DbAttribute pk) throws Exception {
+ @Override
+ public Object generatePk(DataNode node, DbAttribute pk, Class<?> javaType) throws Exception {
DbEntity entity = pk.getEntity();
@@ -239,6 +232,17 @@ public class JdbcPkGenerator implements PkGenerator {
}
}
+ if (javaType != null) {
+ ValueObjectTypeRegistry registry = node.getEntityResolver().getValueObjectTypeRegistry();
+ if (registry != null) {
+ ValueObjectType<Object, Long> converter = (ValueObjectType<Object, Long>) registry.getValueType(javaType);
+ if (converter != null) {
+ return converter.toJavaObject(value);
+ }
+ }
+ }
+
+ // legacy behavior for plain numeric PKs
if (pk.getType() == Types.BIGINT) {
return value;
} else {
diff --git a/cayenne/src/main/java/org/apache/cayenne/dba/PkGenerator.java b/cayenne/src/main/java/org/apache/cayenne/dba/PkGenerator.java
index 440ce5ec4..a7a79222f 100644
--- a/cayenne/src/main/java/org/apache/cayenne/dba/PkGenerator.java
+++ b/cayenne/src/main/java/org/apache/cayenne/dba/PkGenerator.java
@@ -19,12 +19,12 @@
package org.apache.cayenne.dba;
-import java.util.List;
-
import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
+import java.util.List;
+
/**
* Defines methods to support automatic primary key generation.
*/
@@ -66,9 +66,19 @@ public interface PkGenerator {
/**
* Generates a unique and non-repeating primary key for specified PK attribute.
*
- * @since 3.0
+ * @deprecated unused by the framework that relies on {@link #generatePk(DataNode, DbAttribute, Class)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ default Object generatePk(DataNode dataNode, DbAttribute pk) throws Exception {
+ return generatePk(dataNode, pk, null);
+ }
+
+ /**
+ * Generates a unique and non-repeating primary key for the specified PK attribute
+ *
+ * @since 5.0
*/
- Object generatePk(DataNode dataNode, DbAttribute pk) throws Exception;
+ Object generatePk(DataNode dataNode, DbAttribute pk, Class<?> javaType) throws Exception;
/**
* Install the adapter associated with current PkGenerator
diff --git a/cayenne/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerPkGenerator.java b/cayenne/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerPkGenerator.java
index 36800e375..5dd23a2e4 100644
--- a/cayenne/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerPkGenerator.java
+++ b/cayenne/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerPkGenerator.java
@@ -105,14 +105,14 @@ public class SQLServerPkGenerator extends OraclePkGenerator {
}
@Override
- public Object generatePk(DataNode node, DbAttribute pk) throws Exception {
+ public Object generatePk(DataNode node, DbAttribute pk, Class<?> javaType) throws Exception {
DbEntity entity = pk.getEntity();
//check key on UNIQUEIDENTIFIER; UNIQUEIDENTIFIER is a character with a length of 36
if (TypesMapping.isCharacter(pk.getType()) && pk.getMaxLength() == MAX_LENGTH_GUID) {
return guidPkFromDatabase(node, entity);
} else {
- return super.generatePk(node, pk);
+ return super.generatePk(node, pk, javaType);
}
}
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/DataContextExtrasIT.java b/cayenne/src/test/java/org/apache/cayenne/access/DataContextExtrasIT.java
index 1e4ed51b0..eee773d11 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/DataContextExtrasIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/DataContextExtrasIT.java
@@ -253,7 +253,7 @@ public class DataContextExtrasIT {
PkGenerator newGenerator = new JdbcPkGenerator(jdbcAdapter) {
@Override
- public Object generatePk(DataNode node, DbAttribute pk) {
+ public Object generatePk(DataNode node, DbAttribute pk, Class<?> javaType) {
throw new CayenneRuntimeException("Intentional");
}
};
(cayenne) 01/03: CAY-2964 ClassCastException for non-generated meaningful PKs
Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch past-M2
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 5ad7100cd6446bc910c06233de60eb9a70c88362
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Jun 14 13:47:28 2026 -0400
CAY-2964 ClassCastException for non-generated meaningful PKs
test to reproduce the issue
---
.../cayenne/access/DataContextEntityWithMeaningfulPKIT.java | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKIT.java b/cayenne/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKIT.java
index e03514ed9..877740bc5 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/DataContextEntityWithMeaningfulPKIT.java
@@ -336,7 +336,17 @@ public class DataContextEntityWithMeaningfulPKIT {
}
@Test
- public void generatedBigIntegerPK() {
+ public void pkGeneratorMadeBigIntegerPK() {
+ MeaningfulPkBigint pkObj = context.newObject(MeaningfulPkBigint.class);
+
+ context.commitChanges();
+
+ assertNotNull(pkObj.getPk());
+ assertTrue(pkObj.getPk().compareTo(BigInteger.ZERO) > 0);
+ }
+
+ @Test
+ public void dbGeneratedBigIntegerPK() {
MeaningfulPkBigintGenerated pkObj1 = context.newObject(MeaningfulPkBigintGenerated.class);
MeaningfulPkBigintGenerated pkObj2 = context.newObject(MeaningfulPkBigintGenerated.class);
MeaningfulPkBigintGenerated pkObj3 = context.newObject(MeaningfulPkBigintGenerated.class);