Beginning EJB 3

Entity Class As shown in the previous section on inheritance hierarchies, JPA entities may be either concrete or abstract. An abstract entity is simply an entity that cannot be instantiated on its own—it can still be involved in entity relationships and queries, and its fields are persisted following the mapping strategy for its type hierarchy. Listing 4-17 is an example of one of our abstract entities. Listing 4-17. Person.java, an Abstract Root Entity in a JOINED Inheritance Hierarchy /** * Person: An abstract entity, and the root of an inheritance hierarchy */ @Entity @NamedQueries({ @NamedQuery(name = "Person.findAll", query = "select o from Person o")}) @Table(name = "CH04_JOIN_PERSON") @TableGenerator(name = "Person_ID_Generator", table = "CH04_JOIN_PERSON_ID_GEN", pkColumnName = "PRIMARY_KEY_NAME", pkColumnValue = "Person.id", valueColumnName = "NEXT_ID_VALUE") @Inheritance(strategy = InheritanceType.JOINED) public abstract class Person implements Serializable { ... @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name = "HOME_ADDRESS") private Address homeAddress; ... } Not only is the abstract Person entity queryable (here we have defined a "Person.findAll" named query), it also holds an association with the Address entity that is shared by all of its subclasses. Although Person is abstract, it can specify its own mappings and its own table. It just won’t have its own discriminator value, since there will never be a concrete entity instance of the base class Person. Chapter 4 ■ advanCed persistenCe Features 127 Mapped Superclass (@MappedSuperclass) A mapped superclass is a non-entity class that is nonetheless recognized by the persistence manager, and which declares persistent fields and their mappings. Since it is not an entity, it may not be the target of persistent entity relationships, nor may it be used in JPQL queries. It may, however, provide persistent properties common to any entities that extend it, whether directly or indirectly. Starting with the previous inheritance example, let us transform the root entity, Person, into a mapped superclass. Listings 4-18 and 4-19 show the transformed classes. Listing 4-18. Person.java, an Abstract Mapped Superclass (Non-Entity) /** * Person: A Mapped Superclass, and the base class (but not the root entity) * of an inheritance hierarchy * * To create ID generator table "CH04_MS_PERSON_ID_GEN": CREATE TABLE * "CH04_MS_PERSON_ID_GEN" ("PRIMARY_KEY_NAME" VARCHAR2(4000) PRIMARY KEY, * "NEXT_ID_VALUE" NUMBER(38)); * * To initialize this table with data for this entity's ID generator 'Person.id' * (starting with value '0'): INSERT INTO "CH04_MS_PERSON_ID_GEN" VALUES * ('Person.id', 0); */ @MappedSuperclass @TableGenerator(name = "Person_ID_Generator", table = "CH04_MS_PERSON_ID_GEN", pkColumnName = "PRIMARY_KEY_NAME", pkColumnValue = "Person.id", valueColumnName = "NEXT_ID_VALUE") public abstract class Person implements Serializable { @SuppressWarnings("compatibility:-7074714881275658754") private static final long serialVersionUID = 5291172566067954515L; @Id @Column(nullable = false) @GeneratedValue(strategy = GenerationType.TABLE, generator = "Person_ID_Generator") private Integer id; @Column(name = "FIRST_NAME", length = 400) private String firstName; @Column(name = "LAST_NAME", length = 400) private String lastName; @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name = "HOME_ADDRESS") private Address homeAddress; @Version private Integer version;