| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>7. Discriminator</title><link rel="stylesheet" href="css/docbook.css" type="text/css"><base href="display"><meta name="generator" content="DocBook XSL Stylesheets V1.72.0"><link rel="start" href="manual.html" title="Apache OpenJPA 2.0 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" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jpa_overview_mapping_discrim"></a>7. |
| Discriminator |
| </h2></div></div></div><a class="indexterm" name="d0e12843"></a><a class="indexterm" name="d0e12846"></a><a class="indexterm" name="d0e12853"></a><p> |
| The <a 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 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 type="disc"><li><p> |
| <code class="literal">String name</code>: The column name. Defaults to <code class="literal">DTYPE |
| </code>. |
| </p></li><li><p> |
| <code class="literal">length</code>: For string discriminator values, the length of the |
| column. Defaults to 31. |
| </p></li><li><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 href="jpa_overview_mapping_column.html" title="3. Column">Section 3, “ |
| Column |
| ”</a>. |
| </p></li><li><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 type="disc"><li><p> |
| <code class="literal">name</code> |
| </p></li><li><p> |
| <code class="literal">length</code> |
| </p></li><li><p> |
| <code class="literal">column-definition</code> |
| </p></li><li><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 type="1"><li><p> |
| The base entity explicitly declares an inheritance type of <code class="literal"> |
| SINGLE_TABLE</code>. |
| </p></li><li><p> |
| The base entity sets a discriminator value. |
| </p></li><li><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 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" cellspacing="0" cellpadding="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"><a name="jpa_overview_mapping_discrimex"></a><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> |