Depending on the type of persistent objects and the database design, primary key values can be handled in a few different ways. A decision to use one or another technique will affect how the mapping is done. Here is a summary of possible scenarios. Each one is described below in details.
|PK Has DbAttribute||PK Has ObjAttribute||PK is a DataObject property|
|Meaningful Primary Key||Yes||Yes||Yes|
|Primary Key Derived From Relationship||Yes||No||No|
|Database-Generated Primary Key||Yes||No||No|
|Cayenne-Generated Primary Key||Yes||No||No|
DataObjects can provide their own values for the primary key columns. Sometimes this makes sense, for example if a primary key column contains meaningful data like a Social Security Number. In such cases primary key handling is no different from handling any other persistent attributes. Each primary key column (DbAttribute) will have an ObjAttribute mapped to it. The Java class implementing DataObject will contain a property described by this ObjAttribute. The value of this property will be saved to the database.
A primary key column of a table may depend on a primary key column of another table. This is normally the case with "join" tables used to resolve many-to-many relationships. In such cases DataObject normally does not contain a property mapped to a PK column. Instead the value is automatically derived by Cayenne from a primary key of a related object using a relationship.
Sometimes databases have their own proprietary mechanism to generate a primary key when a new row is inserted. This feature is called "auto increment" or "identity column". Cayenne supports such primary keys out of the box. For this mechanism to be invoked, the DbEntity primary key generation must be marked as "Database-Generated" in the Modeler. Currently MySQL and SQLServer adapters have this feature turned on by default.
In most cases, the database primary key is a purely relational concept that has no correspondence in the object model. Normally this is a unique sequential number that identifies a row in the database. This means that creating a property in a persistent object that corresponds to a primary key is an artificial step. To avoid doing that Cayenne assigns each object an ObjectId that internally handles the details of primary key handling.
When a new DataObject is saved, and its properties and relationships do not contain primary key values, Cayenne will attempt to automatically generate a key value. Generation mechanism depends on the DbAdapter used and can be customized by users by subclassing one of the included adapters. Adapters shipped with Cayenne use the following default PK generation strategies:
- MySQL, PostgreSQL, HSQL Adapters: use select/update from a special AUTO_PK_TABLE lookup table.
- Oracle Adapter: uses Oracle sequences.
- DB2 Adapter: uses DB2 sequences.
- SQLServer , Sybase Adapters: use a strored procedure tied to AUTO_PK_TABLE lookup table.
- OpenBase Adapter: uses OpenBase specific NEWID mechanism.
To generate the necessary database objects for the primary key autogeneration, use CayenneModeler and follow the instructions given here.
|Cayenne only supports automatic PK generation for a single column per table.|