That exhausts persistence metadata annotations. We present the class definitions for our sample model below:
Example 5.2. Complete Metadata
package org.mag;
@Entity
@IdClass(Magazine.MagazineId.class)
public class Magazine
{
@Id private String isbn;
@Id private String title;
@Version private int version;
private double price; // defaults to @Basic
private int copiesSold; // defaults to @Basic
@OneToOne(fetch=FetchType.LAZY,
cascade={CascadeType.PERSIST,CascadeType.REMOVE})
private Article coverArticle;
@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE})
@OrderBy
private Collection<Article> articles;
@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
private Company publisher;
@Transient private byte[] data;
...
public static class MagazineId
{
...
}
}
@Entity
public class Article
{
@Id private long id;
@Version private int version;
private String title; // defaults to @Basic
private byte[] content; // defaults to @Basic
@ManyToMany(cascade=CascadeType.PERSIST)
@OrderBy("lastName, firstName")
private Collection<Author> authors;
...
}
package org.mag.pub;
@Entity
public class Company
{
@Id private long id;
@Version private int version;
private String name; // defaults to @Basic
private double revenue; // defaults to @Basic
private Address address; // defaults to @Embedded
@OneToMany(mappedBy="publisher", cascade=CascadeType.PERSIST)
private Collection<Magazine> mags;
@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE})
private Collection<Subscription> subscriptions;
...
}
@Entity
public class Author
{
@Id private long id;
@Version private int version;
private String firstName; // defaults to @Basic
private double lastName; // defaults to @Basic
private Address address; // defaults to @Embedded
@ManyToMany(mappedBy="authors", cascade=CascadeType.PERSIST)
private Collection<Article> arts;
...
}
@Embeddable
public class Address
{
private String street; // defaults to @Basic
private String city; // defaults to @Basic
private String state; // defaults to @Basic
private String zip; // defaults to @Basic
...
}
package org.mag.subscribe;
@MappedSuperclass
public abstract class Document
{
@Id private long id;
@Version private int version;
...
}
@Entity
public class Contract
extends Document
{
private String terms; // defaults to @Basic
...
}
@Entity
public class Subscription
{
@Id private long id;
@Version private int version;
private Date startDate; // defaults to @Basic
private double payment; // defaults to @Basic
@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE})
@MapKey(name="num")
private Map<Long,LineItem> lineItems;
...
@Entity
public static class LineItem
extends Contract
{
private String comments; // defaults to @Basic
private double price; // defaults to @Basic
private long num; // defaults to @Basic
@ManyToOne
private Magazine magazine;
...
}
}
@Entity(name="Lifetime")
public class LifetimeSubscription
extends Subscription
{
@Basic(fetch=FetchType.LAZY)
private boolean getEliteClub () { ... }
public void setEliteClub (boolean elite) { ... }
...
}
@Entity(name="Trial")
public class TrialSubscription
extends Subscription
{
public Date getEndDate () { ... }
public void setEndDate (Date end) { ... }
...
}
The same metadata declarations in XML:
<entity-mappings>
<!-- declares a default access type for all entities -->
<access-type>FIELD</access-type>
<mapped-superclass class="org.mag.subscribe.Document">
<attributes>
<id name="id">
<generated-value strategy="IDENTITY"/>
</id>
<version name="version"/>
</attributes>
</mapped-superclass>
<entity class="org.mag.Magazine">
<id-class="org.mag.Magazine$MagazineId"/>
<attributes>
<id name="isbn"/>
<id name="title"/>
<basic name="name"/>
<basic name="price"/>
<basic name="copiesSold"/>
<version name="version"/>
<many-to-one name="publisher" fetch="LAZY">
<cascade>
<cascade-persist/>
</cascade>
</many-to-one>
<one-to-many name="articles">
<order-by/>
<cascade>
<cascade-persist/>
<cascade-remove/>
</cascade>
</one-to-many>
<one-to-one name="coverArticle" fetch="LAZY">
<cascade>
<cascade-persist/>
<cascade-remove/>
</cascade>
</one-to-one>
<transient name="data"/>
</attributes>
</entity>
<entity class="org.mag.Article">
<attributes>
<id name="id"/>
<basic name="title"/>
<basic name="content"/>
<version name="version"/>
<many-to-many name="articles">
<order-by>lastName, firstName</order-by>
</many-to-many>
</attributes>
</entity>
<entity class="org.mag.pub.Company">
<attributes>
<id name="id"/>
<basic name="name"/>
<basic name="revenue"/>
<version name="version"/>
<one-to-many name="mags" mapped-by="publisher">
<cascade>
<cascade-persist/>
</cascade>
</one-to-many>
<one-to-many name="subscriptions">
<cascade>
<cascade-persist/>
<cascade-remove/>
</cascade>
</one-to-many>
</attributes>
</entity>
<entity class="org.mag.pub.Author">
<attributes>
<id name="id"/>
<basic name="firstName"/>
<basic name="lastName"/>
<version name="version"/>
<many-to-many name="arts" mapped-by="authors">
<cascade>
<cascade-persist/>
</cascade>
</many-to-many>
</attributes>
</entity>
<entity class="org.mag.subcribe.Contract">
<attributes>
<basic name="terms"/>
</attributes>
</entity>
<entity class="org.mag.subcribe.Subscription">
<attributes>
<id name="id"/>
<basic name="payment"/>
<basic name="startDate"/>
<version name="version"/>
<one-to-many name="items">
<map-key name="num">
<cascade>
<cascade-persist/>
<cascade-remove/>
</cascade>
</one-to-many>
</attributes>
</entity>
<entity class="org.mag.subscribe.Subscription.LineItem">
<attributes>
<basic name="comments"/>
<basic name="price"/>
<basic name="num"/>
<many-to-one name="magazine"/>
</attributes>
</entity>
<entity class="org.mag.subscribe.LifetimeSubscription" name="Lifetime"
access="PROPERTY">
<attributes>
<basic name="eliteClub" fetch="LAZY"/>
</attributes>
</entity>
<entity class="org.mag.subscribe.TrialSubscription" name="Trial">
<attributes>
<basic name="endDate"/>
</attributes>
</entity>
<embeddable class="org.mag.pub.Address">
<attributes>
<basic name="street"/>
<basic name="city"/>
<basic name="state"/>
<basic name="zip"/>
</attributes>
</embeddable>
</entity-mappings>
Chapter 12, Mapping Metadata will show you how to map your persistent classes to the datastore using additional annotations and XML markup. First, however, we turn to the JPA runtime APIs.