| name | cayenne-modeling |
| description | Use this skill whenever the user wants to edit, inspect, or extend the Cayenne ORM model in a project — adding or modifying entities, attributes, relationships, embeddables, named queries, stored procedures, or DataNodes. Trigger on phrases like 'add an ObjEntity', 'add a DbEntity', 'add a relationship', 'expose this column as an attribute', 'create a new DataMap', 'add a named query', 'create an embeddable', 'add a stored procedure', 'change the attribute type', 'mark this column as nullable', 'rename this entity', or any mention of a Cayenne `*.map.xml` or `cayenne-*.xml` file. Also trigger when the user references modeling concepts (ObjEntity, DbEntity, ObjAttribute, DbAttribute, ObjRelationship, DbRelationship, Embeddable, dbEntityName, deleteRule, db-attribute-path, db-relationship-path, defaultPackage) in the context of a Cayenne-using app. This is the *primary* skill for a-la-carte ORM model manipulation — direct XML edits, not the Modeler GUI. |
cayenne-modeling
Edit Cayenne DataMap (*.map.xml) and project descriptor (cayenne-*.xml) files directly. This is the default path for granular model changes — adding one entity, one relationship, one query. Use the Modeler GUI (cayenne-modeler skill) only for inherently visual work like reverse engineering.
Required reading
Read these before making any edit — they describe the XML formats this skill operates on:
${CLAUDE_PLUGIN_ROOT}/references/project-layout.md — locate the project descriptor and DataMaps in the user's repo.
${CLAUDE_PLUGIN_ROOT}/references/datamap-schema.md — every element shape for *.map.xml.
${CLAUDE_PLUGIN_ROOT}/references/project-descriptor-schema.md — cayenne-*.xml shape.
Step 1 — Locate the right file
Follow project-layout.md. If the user has multiple Cayenne projects and the request is ambiguous, ask which one. Cache the answer for the rest of the session.
Decide whether the change belongs in a DataMap or the project descriptor (table at the end of project-layout.md):
- Entity/relationship/query/embeddable/procedure → DataMap (
*.map.xml).
- DataMap list, DataNode (DB connection) → project descriptor (
cayenne-*.xml).
Step 2 — Make the edit
Apply the change following the schema in datamap-schema.md or project-descriptor-schema.md.
Critical rules
-
Element order matters. The DataMap schema requires this order inside <data-map>: <property>, <procedure>, <embeddable>, <db-entity>, <obj-entity>, <db-relationship>, <obj-relationship>, <query>, <cgen>, <dbImport>. Insert at the right place — don't append blindly.
-
Cross-link consistently.
- An
<obj-entity> references a <db-entity> by dbEntityName="...". Make sure that DbEntity exists.
- An
<obj-attribute> references a DbAttribute by db-attribute-path="COLUMN_NAME". Make sure that column exists on the DbEntity (or on a related one if using a dotted path through a relationship).
- An
<obj-relationship> requires a backing <db-relationship> (or chain of them) via db-relationship-path. Never add an ObjRelationship without the DB-layer counterpart.
- Most FKs need two
<db-relationship> entries, one per direction. They are not auto-derived.
-
Use the right type on attributes.
db-attribute type — JDBC type names: VARCHAR, INTEGER, BIGINT, DATE, TIMESTAMP, BOOLEAN, NUMERIC, BLOB, CLOB, VARBINARY, etc. VARCHAR/CHAR/VARBINARY also need length. NUMERIC/DECIMAL also need scale.
obj-attribute type — Java FQN: java.lang.String, java.lang.Integer, java.util.Date, java.math.BigDecimal, byte[], etc. Use wrapper types (Integer, not int) for nullable columns.
-
PK handling. PK columns get isPrimaryKey="true" isMandatory="true" on the DbAttribute. They are normally not mirrored as ObjAttributes — Cayenne handles them implicitly. Map a PK as an ObjAttribute only if the user wants a "meaningful PK" (visible on the Java side).
-
Preserve formatting. Match the indentation and quote style of the file (the standard Cayenne style uses tabs and double quotes, but follow what's actually in the file you're editing).
Step 3 — Validate the edit conceptually
After writing the XML, mentally walk through:
- Does every
obj-entity.dbEntityName resolve to an existing <db-entity>?
- Does every
obj-attribute.db-attribute-path resolve to a column on the right DbEntity?
- Does every
obj-relationship.db-relationship-path resolve to a chain of existing <db-relationship> entries?
- Are PK and FK columns marked
isMandatory="true" where the DB enforces NOT NULL?
If anything fails, fix it before reporting done.
Step 4 — Offer the right next step
- If you modified entities and the DataMap has a
<cgen> block: suggest invoking the cayenne-cgen skill to regenerate Java classes. Mention which entities are affected.
- If the user added a new entity and there's no Java class yet: same — recommend
cayenne-cgen.
- If the user is asking about a full DB sync (importing many tables, syncing with a changed schema): hand off to
cayenne-reverse-engineer. Do not try to script this via XML edits.
- If the change is structurally messy (bulk renaming relationships, visual graph rework): suggest the
cayenne-modeler skill. Otherwise do not.
Anti-patterns
- Don't hand-edit
_<Entity>.java superclass files. They are regenerated by cgen and your changes will be overwritten. Edit the user <Entity>.java subclass instead.
- Don't add an
obj-relationship without a db-relationship. Cayenne will validate-fail at runtime.
- Don't use primitive Java types (
int, long, boolean) as obj-attribute type for nullable columns. Primitives can't represent NULL. Use wrappers.
- Don't reorder existing elements. The schema requires the order documented above; reordering existing elements may also create noisy diffs.
- Don't run cgen yourself. That's
cayenne-cgen's job — invoke that skill instead of calling the MCP tool directly here.
- Don't suggest
mvn cayenne:cdbimport or any Maven/Gradle plugin goal. Those are explicitly out of scope for this plugin.