5.4. Conclusion

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) { ... }

    ...
}

Chapter 12, Mapping Metadata will show you how to map your persistent classes to the datastore using additional annotations. First, however, we turn to the EJB persistence runtime APIs.