|  | <html><head> | 
|  | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | 
|  | <title>7.  Discriminator</title><base href="display"><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="manual.html" title="Apache OpenJPA 2.4 User's Guide"><link rel="up" href="jpa_overview_mapping.html" title="Chapter 13.  Mapping Metadata"><link rel="prev" href="jpa_overview_mapping_inher.html" title="6.  Inheritance"><link rel="next" href="jpa_overview_mapping_field.html" title="8.  Field Mapping"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">7.  | 
|  | Discriminator | 
|  | </th></tr><tr><td width="20%" align="left"><a accesskey="p" href="jpa_overview_mapping_inher.html">Prev</a> </td><th width="60%" align="center">Chapter 13.  | 
|  | Mapping Metadata | 
|  | </th><td width="20%" align="right"> <a accesskey="n" href="jpa_overview_mapping_field.html">Next</a></td></tr></table><hr></div><div class="section" id="jpa_overview_mapping_discrim"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.  | 
|  | Discriminator | 
|  | </h2></div></div></div> | 
|  |  | 
|  | <a class="indexterm" name="d5e6122"></a> | 
|  | <a class="indexterm" name="d5e6124"></a> | 
|  | <a class="indexterm" name="d5e6128"></a> | 
|  | <p> | 
|  | The <a class="link" href="jpa_overview_mapping_inher.html#jpa_overview_mapping_inher_single" title="6.1.  Single Table">single table</a> | 
|  | inheritance strategy results in a single table containing records for two or | 
|  | more different classes in an inheritance hierarchy. Similarly, using the | 
|  | <a class="link" href="jpa_overview_mapping_inher.html#jpa_overview_mapping_inher_joined" title="6.2.  Joined"> joined</a> strategy | 
|  | results in the superclass table holding records for superclass instances as well | 
|  | as for the superclass state of subclass instances. When selecting data, JPA | 
|  | needs a way to differentiate a row representing an object of one class from a | 
|  | row representing an object of another. That is the job of the <span class="emphasis"><em> | 
|  | discriminator</em></span> column. | 
|  | </p> | 
|  | <p> | 
|  | The discriminator column is always in the table of the base entity. It holds a | 
|  | different value for records of each class, allowing the JPA runtime | 
|  | to determine what class of object each row represents. | 
|  | </p> | 
|  | <p> | 
|  | The <code class="classname">DiscriminatorColumn</code> annotation represents a | 
|  | discriminator column. It has these properties: | 
|  | </p> | 
|  | <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> | 
|  | <p> | 
|  | <code class="literal">String name</code>: The column name. Defaults to <code class="literal">DTYPE | 
|  | </code>. | 
|  | </p> | 
|  | </li><li class="listitem"> | 
|  | <p> | 
|  | <code class="literal">length</code>: For string discriminator values, the length of the | 
|  | column. Defaults to 31. | 
|  | </p> | 
|  | </li><li class="listitem"> | 
|  | <p> | 
|  | <code class="literal">String columnDefinition</code>: This property has the same meaning | 
|  | as the <code class="literal">columnDefinition</code> property on the <code class="classname">Column | 
|  | </code> annotation, described in | 
|  | <a class="xref" href="jpa_overview_mapping_column.html" title="3.  Column">Section 3, “ | 
|  | Column | 
|  | ”</a>. | 
|  | </p> | 
|  | </li><li class="listitem"> | 
|  | <p> | 
|  | <code class="literal">DiscriminatorType discriminatorType</code>: Enum value declaring | 
|  | the discriminator strategy of the hierarchy. | 
|  | </p> | 
|  | </li></ul></div> | 
|  | <p> | 
|  | The corresponding XML element is <code class="literal"> discriminator-column</code>. Its | 
|  | attributes mirror the annotation properties above: | 
|  | </p> | 
|  | <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> | 
|  | <p> | 
|  | <code class="literal">name</code> | 
|  | </p> | 
|  | </li><li class="listitem"> | 
|  | <p> | 
|  | <code class="literal">length</code> | 
|  | </p> | 
|  | </li><li class="listitem"> | 
|  | <p> | 
|  | <code class="literal">column-definition</code> | 
|  | </p> | 
|  | </li><li class="listitem"> | 
|  | <p> | 
|  | <code class="literal">discriminator-type</code>: One of <code class="literal">STRING</code>, | 
|  | <code class="literal">CHAR</code>, or <code class="literal">INTEGER</code>. | 
|  | </p> | 
|  | </li></ul></div> | 
|  | <p> | 
|  | The <code class="classname">DiscriminatorValue</code> annotation specifies the | 
|  | discriminator value for each class. Though this annotation's value is always a | 
|  | string, the implementation will parse it according to the <code class="classname"> | 
|  | DiscriminatorColumn</code>'s <code class="literal">discriminatorType</code> property | 
|  | above. The type defaults to <code class="literal">DiscriminatorType.STRING</code>, but | 
|  | may be <code class="literal"> DiscriminatorType.CHAR</code> or <code class="literal"> | 
|  | DiscriminatorType.INTEGER</code>. If you do not specify a <code class="classname"> | 
|  | DiscriminatorValue</code>, the provider will choose an appropriate | 
|  | default. | 
|  | </p> | 
|  | <p> | 
|  | The corresponding XML element is <code class="literal">discriminator-value</code>. The | 
|  | text within this element is parsed as the discriminator value. | 
|  | </p> | 
|  | <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3> | 
|  | <p> | 
|  | OpenJPA assumes your model employs a discriminator column if any of the | 
|  | following are true: | 
|  | </p> | 
|  | <div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> | 
|  | <p> | 
|  | The base entity explicitly declares an inheritance type of <code class="literal"> | 
|  | SINGLE_TABLE</code>. | 
|  | </p> | 
|  | </li><li class="listitem"> | 
|  | <p> | 
|  | The base entity sets a discriminator value. | 
|  | </p> | 
|  | </li><li class="listitem"> | 
|  | <p> | 
|  | The base entity declares a discriminator column. | 
|  | </p> | 
|  | </li></ol></div> | 
|  | <p> | 
|  | Only <code class="literal">SINGLE_TABLE</code> inheritance hierarchies require a | 
|  | discriminator column and values. <code class="literal"> JOINED</code> hierarchies can use | 
|  | a discriminator to make some operations more efficient, but do not require one. | 
|  | <code class="literal">TABLE_PER_CLASS</code> hierarchies have no use for a discriminator. | 
|  | </p> | 
|  | <p> | 
|  | OpenJPA defines additional discriminator strategies; see | 
|  | <a class="xref" href="ref_guide_mapping_jpa.html" title="7.  Additional JPA Mappings">Section 7, “ | 
|  | Additional JPA Mappings | 
|  | ”</a> in the Reference Guide for | 
|  | details. OpenJPA also supports final entity classes. OpenJPA does not use a | 
|  | discriminator on final classes. | 
|  | </p> | 
|  | </div> | 
|  | <p> | 
|  | We can now translate our newfound knowledge of JPA discriminators into concrete | 
|  | JPA mappings. We first extend our diagram with discriminator columns: | 
|  | </p> | 
|  | <div class="mediaobject"><table border="0" summary="manufactured viewport for HTML img" style="cellpadding: 0; cellspacing: 0;" width="341"><tr><td><img src="img/jpa-discrim-all.png"></td></tr></table></div> | 
|  | <p> | 
|  | Next, we present the updated mapping document. Notice that in this version, we | 
|  | have removed explicit inheritance annotations when the defaults sufficed. Also, | 
|  | notice that entities using the default <code class="literal">DTYPE</code> discriminator | 
|  | column mapping do not need an explicit <code class="classname">DiscriminatorColumn | 
|  | </code> annotation. | 
|  | </p> | 
|  | <div class="example" id="jpa_overview_mapping_discrimex"><p class="title"><b>Example 13.9.  | 
|  | Discriminator Mapping | 
|  | </b></p><div class="example-contents"> | 
|  |  | 
|  | <pre class="programlisting"> | 
|  | package org.mag; | 
|  |  | 
|  | @Entity | 
|  | @IdClass(Magazine.MagazineId.class) | 
|  | @Table(name="MAG") | 
|  | @DiscriminatorValue("Mag") | 
|  | public class Magazine { | 
|  |  | 
|  | @Column(length=9) | 
|  | @Id private String isbn; | 
|  | @Id private String title; | 
|  |  | 
|  | ... | 
|  |  | 
|  | public static class MagazineId { | 
|  | ... | 
|  | } | 
|  | } | 
|  |  | 
|  | @Entity | 
|  | @Table(name="ART", uniqueConstraints=@Unique(columnNames="TITLE")) | 
|  | @SequenceGenerator(name="ArticleSeq", sequenceName="ART_SEQ") | 
|  | public class Article { | 
|  |  | 
|  | @Id | 
|  | @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ArticleSeq") | 
|  | private long id; | 
|  |  | 
|  | ... | 
|  | } | 
|  |  | 
|  |  | 
|  | package org.mag.pub; | 
|  |  | 
|  | @Entity | 
|  | @Table(name="COMP") | 
|  | public class Company { | 
|  |  | 
|  | @Column(name="CID") | 
|  | @Id private long id; | 
|  |  | 
|  | ... | 
|  | } | 
|  |  | 
|  | @Entity | 
|  | @Table(name="AUTH") | 
|  | public class Author { | 
|  |  | 
|  | @Id | 
|  | @GeneratedValue(strategy=GenerationType.TABLE, generator="AuthorGen") | 
|  | @TableGenerator(name="AuthorGen", table="AUTH_GEN", pkColumnName="PK", | 
|  | valueColumnName="AID") | 
|  | @Column(name="AID", columnDefinition="INTEGER64") | 
|  | private long id; | 
|  |  | 
|  | ... | 
|  | } | 
|  |  | 
|  | @Embeddable | 
|  | public class Address { | 
|  | ... | 
|  | } | 
|  |  | 
|  |  | 
|  | package org.mag.subscribe; | 
|  |  | 
|  | @MappedSuperclass | 
|  | public abstract class Document { | 
|  |  | 
|  | @Id | 
|  | @GeneratedValue(strategy=GenerationType.IDENTITY) | 
|  | private long id; | 
|  |  | 
|  | ... | 
|  | } | 
|  |  | 
|  | @Entity | 
|  | @Table(schema="CNTRCT") | 
|  | @Inheritance(strategy=InheritanceType.JOINED) | 
|  | @DiscriminatorColumn(name="CTYPE") | 
|  | public class Contract | 
|  | extends Document { | 
|  | ... | 
|  | } | 
|  |  | 
|  | @Entity | 
|  | @Table(name="SUB", schema="CNTRCT") | 
|  | @DiscriminatorColumn(name="KIND", discriminatorType=DiscriminatorType.INTEGER) | 
|  | @DiscriminatorValue("1") | 
|  | public class Subscription { | 
|  |  | 
|  | @Id | 
|  | @GeneratedValue(strategy=GenerationType.IDENTITY) | 
|  | private long id; | 
|  |  | 
|  | ... | 
|  |  | 
|  | @Entity | 
|  | @Table(name="LINE_ITEM", schema="CNTRCT") | 
|  | public static class LineItem | 
|  | extends Contract { | 
|  | ... | 
|  | } | 
|  | } | 
|  |  | 
|  | @Entity(name="Lifetime") | 
|  | @DiscriminatorValue("2") | 
|  | public class LifetimeSubscription | 
|  | extends Subscription { | 
|  | ... | 
|  | } | 
|  |  | 
|  | @Entity(name="Trial") | 
|  | @DiscriminatorValue("3") | 
|  | public class TrialSubscription | 
|  | extends Subscription { | 
|  | ... | 
|  | } | 
|  | </pre> | 
|  | <p> | 
|  | The same metadata expressed in XML: | 
|  | </p> | 
|  | <pre class="programlisting"> | 
|  | <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" | 
|  | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 
|  | xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" | 
|  | version="1.0"> | 
|  | <mapped-superclass class="org.mag.subscribe.Document"> | 
|  | <attributes> | 
|  | <id name="id"> | 
|  | <generated-value strategy="IDENTITY"/> | 
|  | </id> | 
|  | ... | 
|  | </attributes> | 
|  | </mapped-superclass> | 
|  | <entity class="org.mag.Magazine"> | 
|  | <table name="MAG"/> | 
|  | <id-class="org.mag.Magazine.MagazineId"/> | 
|  | <discriminator-value>Mag</discriminator-value> | 
|  | <attributes> | 
|  | <id name="isbn"> | 
|  | <column length="9"/> | 
|  | </id> | 
|  | <id name="title"/> | 
|  | ... | 
|  | </attributes> | 
|  | </entity> | 
|  | <entity class="org.mag.Article"> | 
|  | <table name="ART"> | 
|  | <unique-constraint> | 
|  | <column-name>TITLE</column-name> | 
|  | </unique-constraint> | 
|  | </table> | 
|  | <sequence-generator name="ArticleSeq" sequence-name="ART_SEQ"/> | 
|  | <attributes> | 
|  | <id name="id"> | 
|  | <generated-value strategy="SEQUENCE" generator="ArticleSeq"/> | 
|  | </id> | 
|  | ... | 
|  | </attributes> | 
|  | </entity> | 
|  | <entity class="org.mag.pub.Company"> | 
|  | <table name="COMP"/> | 
|  | <attributes> | 
|  | <id name="id"> | 
|  | <column name="CID"/> | 
|  | </id> | 
|  | ... | 
|  | </attributes> | 
|  | </entity> | 
|  | <entity class="org.mag.pub.Author"> | 
|  | <table name="AUTH"/> | 
|  | <attributes> | 
|  | <id name="id"> | 
|  | <column name="AID" column-definition="INTEGER64"/> | 
|  | <generated-value strategy="TABLE" generator="AuthorGen"/> | 
|  | <table-generator name="AuthorGen" table="AUTH_GEN" | 
|  | pk-column-name="PK" value-column-name="AID"/> | 
|  | </id> | 
|  | ... | 
|  | </attributes> | 
|  | </entity> | 
|  | <entity class="org.mag.subcribe.Contract"> | 
|  | <table schema="CNTRCT"/> | 
|  | <inheritance strategy="JOINED"/> | 
|  | <discriminator-column name="CTYPE"/> | 
|  | <attributes> | 
|  | ... | 
|  | </attributes> | 
|  | </entity> | 
|  | <entity class="org.mag.subcribe.Subscription"> | 
|  | <table name="SUB" schema="CNTRCT"/> | 
|  | <inheritance strategy="SINGLE_TABLE"/> | 
|  | <discriminator-value>1</discriminator-value> | 
|  | <discriminator-column name="KIND" discriminator-type="INTEGER"/> | 
|  | <attributes> | 
|  | <id name="id"> | 
|  | <generated-value strategy="IDENTITY"/> | 
|  | </id> | 
|  | ... | 
|  | </attributes> | 
|  | </entity> | 
|  | <entity class="org.mag.subscribe.Subscription.LineItem"> | 
|  | <table name="LINE_ITEM" schema="CNTRCT"/> | 
|  | <primary-key-join-column name="ID" referenced-column-name="PK"/> | 
|  | ... | 
|  | </entity> | 
|  | <entity class="org.mag.subscribe.LifetimeSubscription" name="Lifetime"> | 
|  | <discriminator-value>2</discriminator-value> | 
|  | ... | 
|  | </entity> | 
|  | <entity class="org.mag.subscribe.TrialSubscription" name="Trial"> | 
|  | <discriminator-value>3</discriminator-value> | 
|  | ... | 
|  | </entity> | 
|  | </entity-mappings> | 
|  | </pre> | 
|  | </div></div><br class="example-break"> | 
|  | </div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="jpa_overview_mapping_inher.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="jpa_overview_mapping.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="jpa_overview_mapping_field.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6.  | 
|  | Inheritance | 
|  |  </td><td width="20%" align="center"><a accesskey="h" href="manual.html">Home</a></td><td width="40%" align="right" valign="top"> 8.  | 
|  | Field Mapping | 
|  | </td></tr></table></div></body></html> |