Enumerations
Cayenne Version | 3.0.2 |
Project Directory | InsertingObjects/Enumerations |
Source Directory | InsertingObjects/Enumerations/src/main/java |
Resource Directory | InsertingObjects/Enumerations/src/main/resources | Inputs | N/A |
Compiling/Running |
cd InsertingObjects/Enumerations mvn clean compile mvn exec:java -Dexec.mainClass=cbe.inserting.Enumerations |
View/Edit Model | mvn cayenne-modeler:run | Status |
Code: Mostly Complete Documentation: In-Progress |
Cayenne can natively map database values to Java enumerations.
There are a couple good reasons for doing so. Firstly, the Cayenne data objects will have setters/getters that receive/return the enumeration values instead of strings or numbers. This makes it much harder to accidentally set the wrong value, especially with misspelled values. Second, Java ensures that like enumerations are inherently equal, so you can use the ==
operator on them.
To tell Cayenne to use an enumeration, open Cayenne Modeler and go to the Attributes
tab for your Java class. It may be a little confusing, but the pulldown list of types under the Java Types
column is actually editable and you can type your own values there. Enter the full dotted package name plus class name of your enumeration (just like Cayenne Modeler includes the full name for Java types, such as java.lang.String
).
Once you have edited your model and saved it, generate your Java class again.
Simple Enumerations
Cayenne's basic support is to map your enumeration's name or ordinal value to a database column, depending on if the target database column is a VARCHAR
OR NUMBER
, respectively.
Given an enumeration defined as:
1 public enum Color
2 {
3 RED, GREEN, BLUE;
4 }
You will end up with the following Java-to-Database mappings.
Java Enumeration | DB Value (VARCHAR) | DB Value (NUMBER) |
---|---|---|
RED | 'RED' | 0 |
GREEN | 'GREEN' | 1 |
BLUE | 'BLUE' | 2 |
While this is fine for simple enumerations, it can be limiting and fragile, especially when you are mapping to NUMBER
columns. If the order ever changes or new values are introduced at the beginning or in the middle, all of your previously persisted values will no longer map correctly, because the mapped values are determined by their declared order.
To gain more control, you must use extended enumerations.
Extended Enumerations
Cayenne's extended enumeration support allows you to specify exactly what each Java enumeration maps to in the database. To do this, though, you have to help Cayenne out by implementing the ExtendedEnumeration
interface and provide a single method: getDatabaseValue
.
Having control over the mapping ensures you won't get bitten by position changes and also allows you to use richer Java names even when the values in the database are cryptic. For example, QUARTERLY
could map to 4
.
This example only deals with extended enumerations. An enumeration for RoleType
has been created:
1 package cbe.inserting.constants;
2
3 import org.apache.cayenne.ExtendedEnumeration;
4
5 public enum RoleType implements ExtendedEnumeration
6 {
7 ADMIN("A"), AUTHOR("W"), EDITOR("E"), MODERATOR("M"), NONE("N");
8
9 private String databaseValue;
10
11 private RoleType(String value)
12 {
13 databaseValue = value;
14 }
15
16 @Override
17 public Object getDatabaseValue()
18 {
19 return databaseValue;
20 }
21 }
To be continued...