| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>9. The Complete Mappings</title><base href="display"><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.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_field.html" title="8. Field Mapping"><link rel="next" href="jpa_overview_conclusion.html" title="Chapter 14. Conclusion"></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">9. |
| The Complete Mappings |
| </th></tr><tr><td width="20%" align="left"><a accesskey="p" href="jpa_overview_mapping_field.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_conclusion.html">Next</a></td></tr></table><hr></div><div class="section" title="9. The Complete Mappings"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="jpa_overview_mapping_full">9. |
| The Complete Mappings |
| </h2></div></div></div> |
| |
| <p> |
| We began this chapter with the goal of mapping the following object model: |
| </p> |
| <div class="mediaobject"><table border="0" summary="manufactured viewport for HTML img" cellspacing="0" cellpadding="0" width="369"><tr><td><img src="img/jpa-meta-model.png"></td></tr></table></div> |
| <p> |
| That goal has now been met. In the course of explaining JPA's object-relational |
| mapping metadata, we slowly built the requisite schema and mappings for the |
| complete model. First, the database schema: |
| </p> |
| <div class="mediaobject"><table border="0" summary="manufactured viewport for HTML img" cellspacing="0" cellpadding="0" width="326"><tr><td><img src="img/jpa-data-model.png"></td></tr></table></div> |
| <p> |
| And finally, the complete entity mappings. We have trimmed the mappings to take |
| advantage of JPA defaults where possible. |
| </p> |
| <div class="example"><a name="jpa_overview_mapping_fullex"></a><p class="title"><b>Example 13.17. |
| Full Entity Mappings |
| </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; |
| |
| @Column(name="VERS") |
| @Version private int version; |
| |
| private String name; |
| private double price; |
| |
| @Column(name="COPIES") |
| private int copiesSold; |
| |
| @OneToOne(fetch=FetchType.LAZY, |
| cascade={CascadeType.PERSIST,CascadeType.REMOVE}) |
| @JoinColumn(name="COVER_ID") |
| private Article coverArticle; |
| |
| @OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE}) |
| @OrderBy |
| @JoinTable(name="MAG_ARTS", |
| joinColumns={ |
| @JoinColumn(name="MAG_ISBN", referencedColumnName="ISBN"), |
| @JoinColumn(name="MAG_TITLE", referencedColumnName="TITLE") |
| }, |
| inverseJoinColumns=@JoinColumn(name="ART_ID")) |
| private Collection<Article> articles; |
| |
| @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST) |
| @JoinColumn(name="PUB_ID") |
| private Company publisher; |
| |
| @Transient private byte[] data; |
| |
| |
| ... |
| |
| 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; |
| |
| @Column(name="VERS") |
| @Version private int version; |
| |
| private String title; |
| private byte[] content; |
| |
| @ManyToMany(cascade=CascadeType.PERSIST) |
| @OrderBy("lastName, firstName") |
| @JoinTable(name="ART_AUTHS", |
| joinColumns=@JoinColumn(name="ART_ID"), |
| inverseJoinColumns=@JoinColumn(name="AUTH_ID")) |
| private Collection<Author> authors; |
| |
| ... |
| } |
| |
| |
| package org.mag.pub; |
| |
| @Entity |
| @Table(name="COMP") |
| public class Company { |
| |
| @Column(name="CID") |
| @Id private long id; |
| |
| @Column(name="VERS") |
| @Version private int version; |
| |
| private String name; |
| |
| @Column(name="REV") |
| private double revenue; |
| |
| @Embedded |
| @AttributeOverrides({ |
| @AttributeOverride(name="street", column=@Column(name="STRT")), |
| @AttributeOverride(name="city", column=@Column(name="ACITY")) |
| }) |
| private Address address; |
| |
| @OneToMany(mappedBy="publisher", cascade=CascadeType.PERSIST) |
| private Collection<Magazine> mags; |
| |
| @OneToMany(cascade=CascadeType.PERSIST,CascadeType.REMOVE) |
| @JoinTable(name="COMP_SUBS", |
| joinColumns=@JoinColumn(name="COMP_ID"), |
| inverseJoinColumns=@JoinColumn(name="SUB_ID")) |
| private Collection<Subscription> subscriptions; |
| |
| ... |
| } |
| |
| @Entity |
| @Table(name="AUTH") |
| public class Author { |
| |
| @Id |
| @GeneratedValue(strategy=GenerationType.TABLE, generator="AuthorGen") |
| @TableGenerator(name="AuthorGen", tableName="AUTH_GEN", pkColumnName="PK", |
| valueColumnName="AID") |
| @Column(name="AID", columnDefinition="INTEGER64") |
| private long id; |
| |
| @Column(name="VERS") |
| @Version private int version; |
| |
| @Column(name="FNAME") |
| private String firstName; |
| |
| @Column(name="LNAME") |
| private String lastName; |
| |
| private Address address; |
| |
| @ManyToMany(mappedBy="authors", cascade=CascadeType.PERSIST) |
| private Collection<Article> arts; |
| |
| ... |
| } |
| |
| @Embeddable |
| public class Address { |
| |
| private String street; |
| private String city; |
| @Column(columnDefinition="CHAR(2)") |
| private String state; |
| private String zip; |
| } |
| |
| |
| package org.mag.subscribe; |
| |
| @MappedSuperclass |
| public abstract class Document { |
| |
| @Id |
| @GeneratedValue(strategy=GenerationType.IDENTITY) |
| private long id; |
| |
| @Column(name="VERS") |
| @Version private int version; |
| |
| ... |
| } |
| |
| @Entity |
| @Table(schema="CNTRCT") |
| @Inheritance(strategy=InheritanceType.JOINED) |
| @DiscriminatorColumn(name="CTYPE") |
| public class Contract |
| extends Document { |
| |
| @Lob |
| private String terms; |
| |
| ... |
| } |
| |
| @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; |
| |
| @Column(name="VERS") |
| @Version private int version; |
| |
| @Column(name="START") |
| private Date startDate; |
| |
| @Column(name="PAY") |
| private double payment; |
| |
| @OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE}) |
| @MapKey(name="num") |
| @JoinTable(name="SUB_ITEMS", schema="CNTRCT", |
| joinColumns=@JoinColumn(name="SUB_ID"), |
| inverseJoinColumns=@JoinColumn(name="ITEM_ID")) |
| private Map<Long,LineItem> items; |
| |
| ... |
| |
| @Entity |
| @Table(name="LINE_ITEM", schema="CNTRCT") |
| public static class LineItem |
| extends Contract { |
| |
| @Column(name="COMM") |
| private String comments; |
| |
| private double price; |
| private long num; |
| |
| @ManyToOne |
| @JoinColumns({ |
| @JoinColumn(name="MAG_ISBN", referencedColumnName="ISBN"), |
| @JoinColumn(name="MAG_TITLE", referencedColumnName="TITLE") |
| }) |
| private Magazine magazine; |
| ... |
| } |
| } |
| |
| @Entity(name="Lifetime") |
| @DiscriminatorValue("2") |
| public class LifetimeSubscription |
| extends Subscription { |
| |
| @Basic(fetch=FetchType.LAZY) |
| @Column(name="ELITE") |
| private boolean getEliteClub() { ... } |
| public void setEliteClub(boolean elite) { ... } |
| |
| ... |
| } |
| |
| @Entity(name="Trial") |
| @DiscriminatorValue("3") |
| public class TrialSubscription |
| extends Subscription { |
| |
| @Column(name="END") |
| public Date getEndDate() { ... } |
| public void setEndDate(Date end) { ... } |
| |
| ... |
| } |
| </pre> |
| <p> |
| The same metadata expressed in XML form: |
| </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> |
| <version name="version"> |
| <column name="VERS"/> |
| </version> |
| </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"/> |
| <basic name="name"/> |
| <basic name="price"/> |
| <basic name="copiesSold"> |
| <column name="COPIES"/> |
| </basic> |
| <version name="version"> |
| <column name="VERS"/> |
| </version> |
| <many-to-one name="publisher" fetch="LAZY"> |
| <join-column name="PUB_ID"/> |
| <cascade> |
| <cascade-persist/> |
| </cascade> |
| </many-to-one> |
| <one-to-many name="articles"> |
| <order-by/> |
| <join-table name="MAG_ARTS"> |
| <join-column name="MAG_ISBN" referenced-column-name="ISBN"/> |
| <join-column name="MAG_TITLE" referenced-column-name="TITLE"/> |
| <inverse-join-column name="ART_ID"/> |
| </join-table> |
| <cascade> |
| <cascade-persist/> |
| <cascade-remove/> |
| </cascade> |
| </one-to-many> |
| <one-to-one name="coverArticle" fetch="LAZY"> |
| <join-column name="COVER_ID"/> |
| <cascade> |
| <cascade-persist/> |
| <cascade-remove/> |
| </cascade> |
| </one-to-one> |
| <transient name="data"/> |
| </attributes> |
| </entity> |
| <entity class="org.mag.Article"> |
| <table name="ART"> |
| <unique-constraint> |
| <column-name>TITLE</column-name> |
| </unique-constraint> |
| </table> |
| <sequence-generator name="ArticleSeq", sequenceName="ART_SEQ"/> |
| <attributes> |
| <id name="id"> |
| <generated-value strategy="SEQUENCE" generator="ArticleSeq"/> |
| </id> |
| <basic name="title"/> |
| <basic name="content"/> |
| <version name="version"> |
| <column name="VERS"/> |
| </version> |
| <many-to-many name="articles"> |
| <order-by>lastName, firstName</order-by> |
| <join-table name="ART_AUTHS"> |
| <join-column name="ART_ID" referenced-column-name="ID"/> |
| <inverse-join-column name="AUTH_ID" referenced-column-name="AID"/> |
| </join-table> |
| </many-to-many> |
| </attributes> |
| </entity> |
| <entity class="org.mag.pub.Company"> |
| <table name="COMP"/> |
| <attributes> |
| <id name="id"> |
| <column name="CID"/> |
| </id> |
| <basic name="name"/> |
| <basic name="revenue"> |
| <column name="REV"/> |
| </basic> |
| <version name="version"> |
| <column name="VERS"/> |
| </version> |
| <one-to-many name="mags" mapped-by="publisher"> |
| <cascade> |
| <cascade-persist/> |
| </cascade> |
| </one-to-many> |
| <one-to-many name="subscriptions"> |
| <join-table name="COMP_SUBS"> |
| <join-column name="COMP_ID"/> |
| <inverse-join-column name="SUB_ID"/> |
| </join-table> |
| <cascade> |
| <cascade-persist/> |
| <cascade-remove/> |
| </cascade> |
| </one-to-many> |
| <embedded name="address"> |
| <attribute-override name="street"> |
| <column name="STRT"/> |
| </attribute-override> |
| <attribute-override name="city"> |
| <column name="ACITY"/> |
| </attribute-override> |
| </embedded> |
| </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> |
| <basic name="firstName"> |
| <column name="FNAME"/> |
| </basic> |
| <basic name="lastName"> |
| <column name="LNAME"/> |
| </basic> |
| <version name="version"> |
| <column name="VERS"/> |
| </version> |
| <many-to-many name="arts" mapped-by="authors"> |
| <cascade> |
| <cascade-persist/> |
| </cascade> |
| </many-to-many> |
| <embedded name="address"/> |
| </attributes> |
| </entity> |
| <entity class="org.mag.subcribe.Contract"> |
| <table schema="CNTRCT"/> |
| <inheritance strategy="JOINED"/> |
| <discriminator-column name="CTYPE"/> |
| <attributes> |
| <basic name="terms"> |
| <lob/> |
| </basic> |
| </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> |
| <basic name="payment"> |
| <column name="PAY"/> |
| </basic> |
| <basic name="startDate"> |
| <column name="START"/> |
| </basic> |
| <version name="version"> |
| <column name="VERS"/> |
| </version> |
| <one-to-many name="items"> |
| <map-key name="num"> |
| <join-table name="SUB_ITEMS" schema="CNTRCT"> |
| <join-column name="SUB_ID"/> |
| <inverse-join-column name="ITEM_ID"/> |
| </join-table> |
| <cascade> |
| <cascade-persist/> |
| <cascade-remove/> |
| </cascade> |
| </one-to-many> |
| </attributes> |
| </entity> |
| <entity class="org.mag.subscribe.Subscription.LineItem"> |
| <table name="LINE_ITEM" schema="CNTRCT"/> |
| <attributes> |
| <basic name="comments"> |
| <column name="COMM"/> |
| </basic> |
| <basic name="price"/> |
| <basic name="num"/> |
| <many-to-one name="magazine"> |
| <join-column name="MAG_ISBN" referenced-column-name="ISBN"/> |
| <join-column name="MAG_TITLE" referenced-column-name="TITLE"/> |
| </many-to-one> |
| </attributes> |
| </entity> |
| <entity class="org.mag.subscribe.LifetimeSubscription" name="Lifetime"> |
| <discriminator-value>2</discriminator-value> |
| <attributes> |
| <basic name="eliteClub" fetch="LAZY"> |
| <column name="ELITE"/> |
| </basic> |
| </attributes> |
| </entity> |
| <entity class="org.mag.subscribe.TrialSubscription" name="Trial"> |
| <discriminator-value>3</discriminator-value> |
| <attributes> |
| <basic name="endDate"> |
| <column name="END"/> |
| </basic> |
| </attributes> |
| </entity> |
| <embeddable class="org.mag.pub.Address"> |
| <attributes> |
| <basic name="street"/> |
| <basic name="city"/> |
| <basic name="state"> |
| <column column-definition="CHAR(2)"/> |
| </basic> |
| <basic name="zip"/> |
| </attributes> |
| </embeddable> |
| </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_field.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_conclusion.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8. |
| Field Mapping |
| </td><td width="20%" align="center"><a accesskey="h" href="manual.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 14. |
| Conclusion |
| </td></tr></table></div></body></html> |