@PalmyraMappingConfig#
com.palmyralabs.palmyra.base.annotations.PalmyraMappingConfig
Declares application-managed unique-key and foreign-key constraints for a type. Target: TYPE. Retention: RUNTIME.
When you need it#
By default Palmyra discovers table relationships from JDBC metadata (or a custom schema-introspection query) — it reads primary keys, unique constraints and foreign keys straight off the database. You don’t write this annotation for normally-constrained schemas.
Reach for @PalmyraMappingConfig when those constraints are managed in the application, not the database:
- A shared/read-only schema where you can’t add FK or unique constraints.
- Legacy tables where the data modelling is enforced by application code only.
- Views or staging tables that deliberately omit physical constraints for performance or flexibility reasons.
Declaring the constraints here tells Palmyra to treat them as real — identity lookups (pre-insert existence check, SaveHandler upsert, unique-violation detection) honour the declared unique keys, and joined-attribute resolution (see @PalmyraField.parentRef) follows the declared foreign keys.
@PalmyraUniqueKeyand@PalmyraForeignKeyhaveCLASSretention on their own — they are intended to be consumed only as array members of this annotation.
Attributes#
| Attribute | Signature |
|---|---|
type |
String type() — mapping type identifier (typically matches @PalmyraType.type) |
uniqueKeys |
PalmyraUniqueKey[] uniqueKeys() default {} |
foreignKeys |
PalmyraForeignKey[] foreignKeys() default {} |
Example#
A User table where neither the email-uniqueness constraint nor the tenant foreign key exist in the database, but the application enforces both:
@PalmyraType(type = "User")
@PalmyraMappingConfig(
type = "User",
uniqueKeys = {
@PalmyraUniqueKey(fields = {"loginName"}),
@PalmyraUniqueKey(fields = {"tenantId", "externalId"})
},
foreignKeys = {
@PalmyraForeignKey(
name = "fk_user_tenant",
targetType = "Tenant",
sourceFields = {"tenantId"},
targetFields = {"id"},
targetReference = "tenant"
)
}
)
public class User {
// ...
}With this in place:
- A
SaveHandlercall for{loginName: "ada@example.com"}hits the declared unique key and resolves to the existing row even though the DB doesn’t enforce it. - A
@PalmyraField(parentRef = "tenant", attribute = "name")field onUserflattens correctly because Palmyra now knows how to join — the FK has been declared, not inferred from database metadata.
If you only need to override or add a single constraint on a table that’s otherwise healthy, declare just the relevant entry — Palmyra merges the declared set with whatever it finds in metadata.