Skip Headers
Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide
10g Release 3 (10.1.3)
B14428-02
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

7 Using EJB 3.0 Persistence API

This chapter describes the various options that you can configure in order to use an EJB 3.0 entity.


Note:

In this release, OC4J supports a subset of the functionality specified in the EJB 3.0 public review draft. You may need to make code changes to your EJB 3.0 OC4J application after the EJB 3.0 specification is finalized and OC4J is updated to full EJB 3.0 compliance. For more information, see "Understanding EJB Support in OC4J".

There are no OC4J-proprietary EJB 3.0 annotations. For all OC4J-specific configuration, you must still use the EJB 2.1 orion-ejb-jar.xml file.


Table 7-1 lists these options and indicates which are basic (applicable to most applications) and which are advanced (applicable to more specialized applications).

For more information, see:

Table 7-1 Configurable Options for an EJB 3.0 Entity

Options Type

"Configuring an EJB 3.0 Entity Primary Key"


Basic

"Configuring Table and Column Information"


Basic

"Configuring an EJB 3.0 Entity Container-Managed Relationship Field"


Basic

"Configuring a Basic Mapping"


Basic

"Configuring a Large Object Mapping"


Advanced

"Configuring a Serialized Object Mapping"


Advanced

"Configuring a One-to-One Mapping"


Basic

"Configuring a Many-to-One Mapping"


Basic

"Configuring a One-to-Many Mapping"


Basic

"Configuring a Many-to-Many Mapping"


Basic

"Configuring an Aggregate Mapping"


Advanced

"Configuring Optimistic Lock Version Field"


Advanced

"Using EJB 3.0 Query API"


Basic

"Configuring Inheritance for an EJB 3.0 Entity"


Advanced

"Configuring Lazy Loading on Finder Methods"


Basic

"Configuring Bean Instance Pool Size"


Basic

"Configuring Bean Instance Pool Timeouts for Entity Beans"


Advanced

"Configuring a Lifecycle Callback Method for an EJB 3.0 Entity"


Advanced


Configuring an EJB 3.0 Entity Primary Key

Every EJB 3.0 entity must have a primary key field (see "Configuring an EJB 3.0 Entity Primary Key Field").

You can specify a primary key as a single primitive or JDK object type.

You can either assign primary key values yourself, or, more typically, you can associate a primary key field with a primary key value generator (see "Configuring EJB 3.0 Entity Automatic Primary Key Generation").

Configuring an EJB 3.0 Entity Primary Key Field

You must specify one entity field as the primary key. You can specify a primary key as a single primitive or JDK object type or as a composite primary key class made up of one or more primitive or JDK object types

Typically, you associate the primary key field with a primary key value generator (see "Configuring EJB 3.0 Entity Automatic Primary Key Generation").

Using Annotations

Example 7-1 shows how to use the @Id annotation to specify an entity field as the primary key. In this example, primary key values are generated using a table generator (see "Configuring EJB 3.0 Entity Automatic Primary Key Generation").

Example 7-1 @Id

@Id(generate=TABLE, generator="ADDRESS_TABLE_GENERATOR")
@TableGenerator(
    name="ADDRESS_TABLE_GENERATOR", 
    tableName="EMPLOYEE_GENERATOR_TABLE", 
    pkColumnValue="ADDRESS_SEQ"
)
@Column(name="ADDRESS_ID")
public Integer getId()
{
    return id;
}

Configuring EJB 3.0 Entity Automatic Primary Key Generation

Typically, you associate a primary key field (see "Configuring an EJB 3.0 Entity Primary Key Field") with a primary key value generator so that when an entity instance is created, a new, unique primary key value is assigned automatically.

Table 7-2 lists the types of primary key value generators that you can define.

Table 7-2 EJB 3.0 Entity Primary Key Value Generators

Type Description For more information, see ...

Generated Id Table

A database table the container uses to store generated primary key values for entities. Typically shared by multiple entity types that use table-based primary key generation. Each entity type will typically use its own row in the table to generate the primary key values for that entity class. Primary key values are positive integers.

"Table Sequencing" in the Oracle TopLink Developer's Guide

Table Generator

A primary key generator which you can reference by name, defined at one of the package, class, method, or field level. The level at which you define it will depend upon the desired visibility and sharing of the generator. No scoping or visibility rules are actually enforced. Oracle recommends that you define the generator at the level for which it will be used.

This generator is based on a database table.

"Table Sequencing" in the Oracle TopLink Developer's Guide

Sequence Generator

A primary key generator which you can reference by name, defined at one of the package, class, method, or field level. The level at which you define it will depend upon the desired visibility and sharing of the generator. No scoping or visibility rules are actually enforced. Oracle recommends that you define the generator at the level for which it will be used.

This generator is based on a sequence object that the database server provides.

"Native Sequencing With an Oracle Database Platform" in the Oracle TopLink Developer's Guide

"Native Sequencing With a Non-Oracle Database Platform" in the Oracle TopLink Developer's Guide


Using Annotations

Example 7-2 shows how to use the @GeneratedIdTable annotation to specify a primary key value generator based on a database table. When a new instance of Employee is created, a new value for entity field id is obtained from EMPLOYEE_GENERATOR_TABLE.

Example 7-2 @GeneratedIdTable

@Entity
@Table(name="EJB_EMPLOYEE")
@GeneratedIdTable(
    name="EMPLOYEE_GENERATOR_TABLE", 
    table=@Table(name="EJB_EMPLOYEE_SEQ"), 
    pkColumnName="SEQ_NAME", valueColumnName="SEQ_COUNT"
)
public class Employee implements Serializable
{
...
    @Id(generate=TABLE, generator="EMPLOYEE_GENERATOR_TABLE")
    @Column(name="EMPLOYEE_ID", primaryKey=true)
    public Integer getId()
    {
        return id;
    }
...
}

Example 7-3 shows how to use the @TableGenerator annotation to specify a primary key value generator based on a database table. When a new instance of Employee is created, a new value for entity field id is obtained from EMPLOYEE_GENERATOR_TABLE. You must set the @Id annotation attribute generate to TABLE in this case.

Example 7-3 @TableGenerator

@Entity
@Table(name="EJB_ADDRESS")
public class Address implements Serializable
{
...
    @Id(generate=TABLE, generator="ADDRESS_TABLE_GENERATOR")
    @TableGenerator(
        name="ADDRESS_TABLE_GENERATOR", 
        tableName="EMPLOYEE_GENERATOR_TABLE", 
        pkColumnValue="ADDRESS_SEQ"
    )
    @Column(name="ADDRESS_ID")
    public Integer getId()
    {
        return id;
    }
...
}

Example 7-3 shows how to use the @SequenceGenerator annotation to specify a primary key value generator based on a sequence object provided by the database. When a new instance of Employee is created, a new value for entity field id is obtained from database sequence object ADDRESS_SEQ. You must set the @Id annotation attribute generate to SEQUENCE in this case.

Example 7-4 @SequenceGenerator

@Entity
@Table(name="EJB_ADDRESS")
public class Address implements Serializable
{
...
    @Id(generate=SEQUENCE, generator="ADDRESS_TABLE_GENERATOR")
    @SequenceGenerator(
        name="ADDRESS_TABLE_GENERATOR",
        sequenceName="ADDRESS_SEQ"
    )
    @Column(name="ADDRESS_ID")
    public Integer getId()
    {
        return id;
    }
...
}

Configuring Table and Column Information

You can define the characteristics of the database table into which the TopLink persistence manager persists your entity, including:

This is particularly important if you have an existing database schema.

If you do not have an existing database schema, you can delegate table and column definition to OC4J by omitting this configuration: at deployment time, OC4J will create default table and column names based on class and data member names.

Configuring the Primary Table

The primary table is the table into which the TopLink persistence manager persists your entity: in particular, it is the table that stores the entity's primary key (see "Configuring an EJB 3.0 Entity Primary Key"). Optionally, you can also specify one or more secondary tables (see "Configuring a Secondary Table") if the entity's persistent data is stored across multiple tables.

You define the primary table at the entity class level.

Using Annotations

Example 7-5 shows how to use the @Table annotation to define the primary table for the Employee class. The TopLink persistence manager will persist instances of this entity to a table named EJB_EMPLOYEE.

Example 7-5 @Table

@Entity
@Table(name="EJB_EMPLOYEE")
public class Employee implements Serializable
{
...
}

Configuring a Secondary Table

Specifying one or more secondary tables indicates that the entity's persistent data is stored across multiple tables. You must first specify a primary table (see "Configuring the Primary Table") before you can specify any secondary tables.

You define a secondary table at the entity class level.

If you specify one or more secondary tables, you can specify the secondary table name in the column definition (see "Configuring a Join Column") for persistent fields that are stored in that table. This enables the distribution of entity persistent fields across multiple tables.

Using Annotations

Example 7-6 shows how to use the @SecondaryTable annotation to specify that some of the entity's persistent data is stored in a table named EJB_SALARY.

Example 7-6 @SecondaryTable

@Entity
@Table(name="EJB_EMPLOYEE")
@SecondaryTable(name="EJB_SALARY")
public class Employee implements Serializable
{
...
}

Configuring a Column

The column is, by default, the name of the column in the primary table (see "Configuring the Primary Table") into which the TopLink persistence manager stores the field's value.

You define the column at one of the property (getter or setter method) or field level of your entity.

If you specified one or more secondary tables (see "Configuring a Secondary Table"), you can specify the secondary table name in the column definition. This enables the distribution of entity persistent fields across multiple tables.

Using Annotations

Example 7-7 shows how to use the @Column annotation to specify column F_NAME in the primary table for field firstName.

Example 7-7 @Column for the Primary Table

@Column(name="F_NAME")
public String getFirstName()
{
    return firstName;
}

Example 7-8 shows how to use the @Column annotation to specify column SALARY in secondary table EMP_SALARY for field salary.

Example 7-8 @Column for a Secondary Table

@Column(name="SALARY", secondaryTable="EMP_SALARY")
public String getSalary()
{
    return salary;
}

Configuring a Join Column

A join column specifies a mapped, foreign key column for joining an entity association or a secondary table.

You can define a join column with a:

Using Annotations

Example 7-9 shows how to use the @JoinColumn annotation to specify a join column with a secondary table. For more information, see "Configuring a Secondary Table".

Example 7-9 @JoinColumn with a Secondary Table

@Entity
@Table(name="EJB_EMPLOYEE")
@SecondaryTable(name="EJB_SALARY")
@JoinColumn(name="EMP_ID", referencedColumnName="EMP_ID")
public class Employee implements Serializable
{
...
}

Example 7-10 shows how to use the @JoinColumn annotation to specify a join column with a one-to-one mapping. For more information, see "Configuring a One-to-One Mapping".

Example 7-10 @JoinColumn with a One-to-One Mapping

@OneToOne(cascade=ALL, fetch=LAZY)
@JoinColumn(name="ADDR_ID")
public Address getAddress()
{
    return address;
}

Example 7-11 shows how to use the @JoinColumn annotation to specify a join column with a many-to-one mappiong. For more information, see "Configuring a Many-to-One Mapping".

Example 7-11 @JoinColumn with a Many-to-One Mapping

@ManyToOne(cascade=PERSIST, fetch=LAZY)
@JoinColumn(name="MANAGER_ID", referencedColumnName="EMP_ID")
public Employee getManager()
{
    return manager;
}

Example 7-12 shows how to use the @JoinColumn annotation to specify a join column with a one-to-many mapping. Fore more information, see "Configuring a One-to-Many Mapping".

Example 7-12 @JoinColumn with a One-to-Many Mapping

@OneToMany(cascade=PERSIST)
@JoinColumn(name="MANAGER_ID", referencedColumnName="EMP_ID")
public Collection getManagedEmployees()
{
    return managedEmployees;
}

Configuring an EJB 3.0 Entity Container-Managed Relationship Field

In an EJB 3.0 entity, you define container-managed relationship (CMR) fields (see "What are Container-Managed Relationship Fields?") as follows:


Note:

You can download an EJB 3.0 entity container-managed relationship field code example from: http://www.oracle.com/technology/tech/java/oc4j/ejb3/howtos-ejb3/howtoejb30mappingannotations/doc/how-to-ejb30-mapping-annotations.html.

Configuring a Basic Mapping

Use a basic mapping to map an field that contains a primitive or JDK object value. For example, use a basic mapping to store a String attribute in a VARCHAR column.

You define a basic mapping at one of the property (getter or setter method) or field level of your entity.

For more information, see "Understanding Direct-to-Field Mapping" in the Oracle TopLink Developer's Guide.

Using Annotations

Example 7-13 shows how to use the @Basic annotation to specify a basic mapping for field firstName.

Example 7-13 @Basic

@Basic(fetch=EAGER)
@Column(name="F_NAME")
public String getFirstName()
{
    return firstName;
}

Configuring a Large Object Mapping

Use a large object (LOB) mapping to specify that a persistent property or field should be persisted as a LOB to a database-supported LOB type. A LOB may be either a binary (BLOB) or character (CLOB) type.

You define a large object mapping at one of the property (getter or setter method) or field level of your entity.

For more information, see:

Using Annotations

Example 7-14 shows how to use the @Lob annotation to specify a large object mapping for field image.

Example 7-14 @Lob

@Lob(fetch=EAGER, type=BLOB)
@Column(name="IMAGE")
public Byte[] getImage() 
{
    return image;
}

Configuring a Serialized Object Mapping

Use a serialized object mapping to specify that a persistent property should be persisted as a serialized stream of bytes.

You define a serialized object at one of the property (getter or setter method) or field level of your entity.

For more information, see:

Using Annotations

Example 7-15 shows how to use the @Serialized annotation to specify a serialized object mapping for field picture.

Example 7-15 @Serialized

@Serialized(fetch=EAGER)
@Column(name="PICTURE")
public Byte[] getPicture() 
{
    return picture;
}

Configuring a One-to-One Mapping

Use a one-to-one mapping to represent simple pointer references between two Java objects. In Java, a single pointer stored in an attribute represents the mapping between the source and target objects. Relational database tables implement these mappings using foreign keys.

You define a one-to-one mapping at one of the property (getter or setter method) or field level of your entity.

For more information, see "Understanding One-to-One Mapping" in the Oracle TopLink Developer's Guide.

Using Annotations

Example 7-16 shows how to use the @OneToOne annotation to specify a one-to-one mapping for field address.

Example 7-16 @OneToOne

@OneToOne(cascade=ALL, fetch=LAZY)
@JoinColumn(name="ADDR_ID")
public Address getAddress()
{
    return address;
}

Configuring a Many-to-One Mapping

Use a many-to-one mapping to represent simple pointer references between two Java objects. In Java, a single pointer stored in an attribute represents the mapping between the source and target objects. Relational database tables implement these mappings using foreign keys.

You define a many-to-one mapping at one of the property (getter or setter method) or field level of your entity.

For more information, see "Understanding One-to-One Mapping" in the Oracle TopLink Developer's Guide.

Using Annotations

Example 7-17 shows how to use the @ManyToOne annotation to specify a many-to-one mapping for field manager.

Example 7-17 @ManyToOne

@ManyToOne(cascade=PERSIST, fetch=LAZY)
@JoinColumn(name="MANAGER_ID", referencedColumnName="EMP_ID")
public Employee getManager()
{
    return manager;
}

Configuring a One-to-Many Mapping

Use a one-to-many mapping to represent the relationship between a single source object and a collection of target objects. This relationship is a good example of something that is simple to implement in Java using a Vector (or other collection types) of target objects, but difficult to implement using relational databases.

You define a one-to-many mapping at one of the property (getter or setter method) or field level of your entity.

For more information, see "Understanding One-to-Many Mapping" in the Oracle TopLink Developer's Guide.

Using Annotations

Example 7-18 shows how to use the @OneToMany annotation to specify a one-to-many mapping for field managedEmployees.

Example 7-18 @OneToMany

@OneToMany(cascade=PERSIST)
@JoinColumn(name="MANAGER_ID", referencedColumnName="EMP_ID")
public Collection getManagedEmployees()
{
    return managedEmployees;
}

Configuring a Many-to-Many Mapping

Use a many-to-many mapping to represent the relationships between a collection of source objects and a collection of target objects. This mapping requires the creation of an intermediate table (the association table) for managing the associations between the source and target records.

You define a many-to-many mapping at one of the property (getter or setter method) or field level of your entity.

For more information, see "Understanding Many-to-Many Mapping" in the Oracle TopLink Developer's Guide.

Using Annotations

Example 7-19 shows how to use the @ManyToMany annotation to specify a many-to-many mapping for field projects and how to use the @AssociationTable annotation to specify an association table.

Example 7-19 @ManyToMany

@ManyToMany(cascade=PERSIST)
@AssociationTable(
    table=@Table(name="EJB_PROJ_EMP"),
    joinColumns=@JoinColumn(name="EMP_ID", referencedColumnName="EMP_ID"),
    inverseJoinColumns=@JoinColumn(name="PROJ_ID", referencedColumnName="PROJ_ID")
)
public Collection getProjects()
{
    return projects;
}

Configuring an Aggregate Mapping

Two entities–an owning (parent or source) entity and an owned (child or target) entity–are related by aggregation if there is a strict one-to-one relationship between them and all the attributes of the owned entity can be retrieved from the same table(s) as the owning entity. This means that if the owning entity exists, then the owned entity must also exist and if the owning entity is destroyed, then the owned entity is also destroyed.

An aggregate mapping allows you to associate data members in the owned entity with fields in the owning entity's underlying database tables.

In the owning entity, you designate the owned field or setter as embedded.In owned entity, you designate the class as embeddable and associate it with the owning entity's table name.

In the owning entity, you can override any column specifications (see "Configuring a Column") made in the owned entity.

For more information, see "Understanding Aggregate Mapping" in the Oracle TopLink Developer's Guide.

Using Annotations

Example 7-20 shows how to use the @Embedded annotation to specify an aggregate mapping for field period. This field contains an instance of EmploymentPeriod. Example 7-21 shows how to use the @Embeddable annotation to specify the EmploymentPeriod entity class as being eligible for use in an aggregate mapping and how to use the @Table annotation (see "Configuring the Primary Table") to associate this class with the owning entity's table.

Example 7-20 @Embedded

@Entity
@Table(name="EJB_EMPLOYEE")
public class Employee implements Serializable
{
...
    @Embedded
    public EmploymentPeriod getPeriod()
    {
        return period;
    }
...
}

Example 7-21 @Embeddable

@Embeddable
@Table(name="EJB_EMPLOYEE")
public class EmploymentPeriod implements Serializable
{
    private Date startDate;
    private Date endDate;
...
}

You can use the @AttributeOverride in the owning entity (see Example 7-22) to override the column definitions made in the owned entity (see Example 7-23).

Example 7-22 @Embedded and @AttributeOverride

@Entity
@Table(name="EJB_EMPLOYEE")
public class Employee implements Serializable
{
...
    @Embedded(
        {
            @AttributeOverride(name="startDate", column=@Column("EMP_START")),
            @AttributeOverride(name="endDate", column=@Column("EMP_END"))
        }
    )
    public EmploymentPeriod getPeriod()
    {
        return period;
    }
...
}

Example 7-23 @Embeddable and @Column

@Embeddable
@Table(name="EJB_EMPLOYEE")
public class EmploymentPeriod implements Serializable
{
    @Column("START_DATE")
    private Date startDate;

    @Column("END_DATE")
    private Date endDate;
...
}

Configuring Optimistic Lock Version Field

You can specify an entity field to function as a version field for use in a TopLink optimistic version locking policy. OC4J uses this version field to ensure integrity when reattaching (see "Detaching and Merging an Entity Bean Instance") and for overall optimistic concurrency control.

You define the optimistic lock version field at one of the property (getter or setter method) or field level of your entity.

For more information, see "Optimistic Version Locking Policies" in the Oracle TopLink Developer's Guide.

Using Annotations

Example 7-24 shows how to use the @Version annotation to define an optimistic version locking policy using column VERSION.

Example 7-24 @Version

@Version
@Column(name="VERSION")
public int getVersion()
{
    return version;
}

Configuring Lazy Loading on Finder Methods

Lazy loading is an Oracle-specific option that you configure using the EJB 2.1 orion-ejb-jar.xml file.

For more information, see "Configuring Lazy Loading on Finder Methods".

Configuring a Lifecycle Callback Method for an EJB 3.0 Entity

You can specify an EJB 3.0 entity class method as a callback method for any of the following lifecycle events:

The entity class method must have the following signature:

public int <MethodName>()

For more information, see:

Using Annotations

You can specify an EJB 3.0 entity class method as a lifecycle callback method using any of the following annotations:

  • @PrePersist

  • @PostPersist

  • @PreRemove

  • @PostRemove

  • @PreUpdate

  • @PostUpdate

  • @PostLoad

Example 7-25 shows how to use the @PrePersist annotation to specify EJB 3.0 entity class method initialize as a lifecycle callback method.

Example 7-25 @PrePersist

@PrePersist
public int initialize()
{
  ...
}

Configuring Inheritance for an EJB 3.0 Entity

OC4J supports the following inheritance strategies for mapping a class or class hierarchy to a relational database schema:

You can configure either approach using annotations (see "Using Annotations").

Joined Subclass

In this strategy, fields that are specific to a subclass are mapped to a separate table than the fields that are common to the parent class, and a join is performed to instantiate the subclass.

The root of the class hierarchy is represented by a single table. Each subclass is represented by a separate table that contains the columns that are specific to the subclass (not inherited from its superclass), as well as the column that represent the subclass's primary key. If the subclass does not have any additional state over its superclass, a separate table is not required.

If the subclass table has primary key column, it serves as a foreign key to the primary key of the superclass table. If the subclass table primary key column name is the same as that of the primary key column of the superclass table, OC4J infers this relationship. If the subclass table primary key column name is not the same as that of the primary key column of the superclass table (or, if the subclass table does not have primary key column), you must specify a subclass table column to use to join the primary table of an entity subclass to the primary table of its superclass.

The primary table of the superclass also has a column that serves as a discriminator column, that is, a column whose value identifies the specific subclass to which the instance that is represented by the row belongs.

For more information, see "Configuring Joined Subclass Inheritance with Annotations".

Single Table for each Class Hierarchy

In this strategy, all the classes in a hierarchy are mapped to a single table. The table has a column that serves as a discriminator column. Each subclass that adds additional state maps to this new state only in this single table. Such columns are only used by that subclass.

For more information, see "Configuring Single Table Inheritance with Annotations".

Using Annotations

This section describes the following:

Configuring Joined Subclass Inheritance with Annotations

The following examples show how to configure inheritance using a joined subclass approach (see "Joined Subclass"): Example 7-26 shows how to use the @Inheritance annotation in the base class Project. Example 7-27 and Example 7-28 show how to use the @Inheritance annotation in derived classes LargeProject and SmallProject, respectively.

The primary table is EJB_PROJECT to which both Project and SmallProject are mapped. EJB_PROJECT has a discriminator column called PROJ_TYPE that represents Project, LargeProject and SmallProject with values P, L and S, respectively. LargeProject adds additional state to Project, so is mapped to its own table, EJB_LPROJECT, which contains fields specific to LargeProject, such as BUDGET. Note that EJB_LPROJECT does not have a primary key column; instead it has a foreign key (PROJ_ID) that has the same name as the primary key of EJB_PROJECT.

Note that in Example 7-27, because the LargeProject class primary key column name (LARGE_PROJECT_ID) is not the same as that of the primary key column of the superclass table (ID), you must use the @InheritanceJoinColumn annotation to specify the column used to join the LargeProject primary table to the primary table of its superclass.

Example 7-26 @Inheritance: Base Class Project in Joined Subclass Inheritance

@Entity
@Table(name="EJB_PROJECT")
@Inheritance(strategy=JOINED, discriminatorValue="P")
@DiscriminatorColumn(name="PROJ_TYPE")
public class Project implements Serializable
{
...
    @Id()
    @Column(name="PROJECT_ID", primaryKey=true)
    public Integer getId()
    {
        return id;
    }
...
}

Example 7-27 @Inheritance: Derived Class LargeProject in Joined Subclass Inheritance

@Entity
@Table(name="EJB_LPROJECT")
@Inheritance(discriminatorValue="L")
@InheritanceJoinColumn(name="LARGE_PROJECT_ID")
public class LargeProject extends Project
{
...
    @Id()
    @Column(name="LARGE_PROJECT_ID", primaryKey=true)
    public Integer getProjectId()
    {
        return projectId;
    }
...
}

Example 7-28 @Inheritance: Derived Class SmallProject in Joined Subclass Inheritance

@Entity
@Table(name="EJB_PROJECT")
@Inheritance(discriminatorValue="S")
public class SmallProject extends Project
{
...
}

Configuring Single Table Inheritance with Annotations

The following examples show how to configure inheritance using a single table for each class hierarchy approach (see "Single Table for each Class Hierarchy"): Example 7-26 shows how to use the @Inheritance annotation in the base class Project. Example 7-27 and Example 7-28 show how the @Inheritance annotation is not needed in derived classes LargeProject and SmallProject, respectively.

The primary table is EJB_PROJECT to which both Project and SmallProject are mapped. The EJB_PROJECT table would contain all the columns for Project and an additional column (BUDGET) used only by LargeProject.

Example 7-29 @Inheritance: Base Class Project in Single Table Inheritance

@Entity
@Table(name="EJB_PROJECT")
@Inheritance(strategy=SINGLE_TABLE, discriminatorValue="P")
@DiscriminatorColumn(name="PROJ_TYPE")
public class Project implements Serializable
{
...
}

Example 7-30 @Inheritance: Derived Class LargeProject in Single Table Inheritance

@Entity
@Inheritance(discriminatorValue="L")
public class LargeProject extends Project
{
...
}

Example 7-31 @Inheritance: Derived Class SmallProject in Single Table Inheritance

@Entity
@Inheritance(discriminatorValue="S")
public class SmallProject extends Project
{
...
}