Friday, October 23, 2009

Section 6.2. Defining a Persistent Enumerated Type








6.2. Defining a Persistent Enumerated Type


An enumerated type is a common and
useful programming abstraction allowing a value to be selected
from a fixed set of named choices. These were originally well represented
in Pascal, but C took such a minimal approach (essentially just letting
you assign symbolic names to interchangeable integer values) that early
Java releases reserved C's enum keyword but
declined to implement it. A better, object-oriented approach known as the
"typesafe enum pattern" evolved and was popularized in Joshua Bloch's
Effective Java. This approach required a fair
amount of boilerplate coding, but it lets you do all kinds of interesting
and powerful things. One of the many delightful innovations in the Java 5
specification was the ability to resuscitate the enum keyword as an easy way to get the power of
typesafe enumerations without all the tedious boilerplate coding, and it
provides other nifty benefits.


NOTE


C-style numeric "enumerations" still appear too often in Java.
Older parts of the Sun API contain many of
them.



Regardless of how you implement an enumerated type, you're sometimes
going to want to be able to persist such values to a database. And even
though there is now a standard way to do it in Java, Hibernate doesn't
offer any built-in support. So let's see how to implement a
UserType that can persist an enum for us.


Let's suppose we want to be able to specify whether our tracks came
from cassette tapes, vinyl, VHS tapes,
CDs, a broadcast, an Internet download site, or a
digital audio stream. (We could go really nuts and distinguish between
Internet streams and satellite radio services like Sirius or
XM, or radio versus television broadcast, but this is
plenty to demonstrate the important ideas.)


Without any consideration of persistence, our typesafe enumeration
class might look something like Example 6-1. (The JavaDoc has been compressed to take
less printed space, but the downloadable version is formatted
normally.)


Example 6-1. SourceMedia.java, our initial typesafe enumeration



package com.oreilly.hh;

/**
* This is a typesafe enumeration that identifies the media on which an
* item in our music database was obtained.
*/
public enum SourceMedia {
/** Music obtained from magnetic cassette tape. */
CASSETTE("Audio Cassette Tape"),

/** Music obtained from a vinyl record. */
VINYL("Vinyl Record"),

/** Music obtained from VHS tapes. */
VHS("VHS Videocassette tape"),

/** Music obtained from a broadcast. */
BROADCAST("Analog Broadcast"),

/** Music obtained from a digital compact disc. */
CD("Compact Disc"),

/** Music obtained as an Internet download. */
DOWNLOAD("Internet Download"),

/** Music obtained from a digital audio stream. */
STREAM("Digital Audio Stream");

/**
* Stores the human-readable description of this instance, by which it is
* identified in the user interface.
*/
private final String description;

/**
* Enum constructors are always private since they can only be accessed
* through the enumeration mechanism.
*
* @param description human readable description of the source for the
* audio, by which it is presented in the user interface.
*/
private SourceMedia(String description) {
this.description = description;
}

/**
* Return the description associated with this enumeration instance.
*
* @return the human-readable description by which this value is
* identified in the user interface.
**/
public String getDescription() {
return description;
}
}





Of course, the beauty of working with Hibernate is that we don't
need to change our normal Java classes to add support for persistence.
Even though we've not thought about persistence in designing this enum, we will be able to use it as-is. Now that
we no longer have to consider using the deprecated PersistentEnum interface, defining a
persistent enumerated type is no different than defining any other
enumerated type.


NOTE


The PersistentEnum interface did require
you to change your enumerations for persistence. That was probably an
even bigger reason why it was deprecated than the fact that it did not
mesh well with the Effective Java persistent
enumeration pattern or the Java 5 enum
keyword.



So how do we teach Hibernate to persist values of our
enumeration?









No comments:

Post a Comment