4 Understanding Entities

An entity is a lightweight persistence domain object.

Typically, an entity represents a table in a relational database, and each entity instance corresponds to a row in the table. The primary programming artifact of an entity is the entity class, although entities can use helper classes.

The persistent state of an entity is represented either through persistent fields or persistent properties. These fields or properties use object/relational mapping annotations to map the entities and entity relationships to the relational data in the underlying data store.

Identifying Entities

Use the @Entity annotation to specify that a class is an entity.

Note:

The entity class must also be listed in your persistence.xml file, unless you set the tag <exclude-unlisted-classes> to false.

For more information, see Chapter 2 "Entities" in the JPA Specification.

http://jcp.org/en/jsr/detail?id=338

Date and Time Entities

Java EE 8 introduced a new date and time API under the package java.time.

Prior to Java EE 8, the existing date and time classes such as java.util.Date and SimpleDateFormatter were not thread-safe, had a poor design, and inefficient time zone handling, leading to concurrency issues for users.

The new date-time API contains the following classes:
  • Local date-time : Simplified date-time API with no timezone handling.

  • Zoned date-time : Specialized date-time API to deal with various timezones.

  • Period and Duration : Period deals with date and Duration deals with time based amount of time.

  • ChronoUnits Enum : java.time.temporal.ChronoUnit enum in Java 8, replaces integer values used in old API to represent day, month, and so on.

  • TemporalAdjuster : Used to perform date related operations.

For JavaSE java.time APIs, see https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html.

Allowing AttributeConverters to be CDI Injectable

Attribute converter classes in Java EE environments support dependency injection through the Contexts and Dependency Injection API (CDI).

The CDI injection into the AttributeConverter class allows you to inject reusable conversion implementation into the AttributeConverter. An AttributeConverter implements the javax.persistence.AttributeConverter interface, through which the converter implementation class must be annotated with the Converter annotation.

An attribute converter class defines the lifecycle callback methods annotated with the PostConstruct and PreDestroy annotations. These methods are invoked after injection has taken place and before the attribute converter instance is destroyed respectively.

For example, if X and Y types are entities of the same Java type and if:

  • @param X is a type of the entity attribute
  • @param Y is a type of the database column
public interface AttributeConverter<X,Y> {
	public Y convertToDatabaseColumn (X attribute);
	public X convertToEntityAttribute (Y dbData);
}

The persistence provider uses the CDI SPI to create instances of the attribute converter class and performs an injection to invoke the PostConstruct and PreDestroy methods, if any, to dispose the attribute converter instances.

Entities and Persistent Identity

Every entity must have a persistent identity, which is an equivalent of a primary key in a database table that stores the entity state.

By default, the EclipseLink persistence provider assumes that each entity has at least one field or property that serves as a primary key.

You can generate and/or configure the identity of your entities by using the following annotations:

  • @Id

  • @IdClass

  • @EmbeddedId

  • @GeneratedValue

  • @TableGenerator

  • @SequenceGenerator

  • @UuidGenerator

You can also use these annotations to fine-tune how your database maintains the identity of your entities. For more information on these annotations, see "Metadata for Object/Relational Mapping" in the JPA Specification.

http://jcp.org/en/jsr/detail?id=338

Entities and Database Tables

Every entity class maps to a specific table or set of tables in the database.

By default, the entity's table name is defaulted as its entity name as uppercase, which defaults to the entity's short class name. An entity normally maps to a single table, but can also map to multiple tables, or even a view.

You can customize an entity's tables using the following annotations:

  • @Table

  • @SecondaryTable

Entities and Inheritance

JPA defines several difference methods for persisting objects with inheritance.

The @Inheritance annotation is used in the root class to define SINGLE_TABLE, JOINED, and TABLE_PER_CLASS inheritance. For abstract classes that define common state or persistence behavior, but have no relationship on the database, the @MappedSuperclass annotation can be used.

  • @Inheritance

  • @MappedSuperclass

Entities and Embedded Objects

An embeddable is a special type of class that is not directly persistent, but persisted only with its parent entity.

You can use the @Embeddable annotation to map an embedded class. An embeddable can be referenced from an entity or another embeddable using the @Embedded annotation for a single reference, @EmbeddedId for an embedded id, or the @ElementCollection annotation for a Collection or Map reference. An embeddable can also be used in any Map key using the @MapKeyClass annotation.

  • @Embeddable

  • @EmbeddedId

  • @Embedded

  • @ElementCollection

Entities and Sequence Generation

Many databases support an internal mechanism for id generation called sequences.

You can use a database sequence to generate identifiers when the underlying database supports them.

  • @SequenceGenerator—If you use the @GeneratedValue annotation to specify a primary key generator of type SEQUENCE, then you can use the @SequenceGenerator annotation to fine-tune this primary key generator to do the following:

    • change the allocation size to match your application requirements or database performance parameters

    • change the initial value to match an existing data model (for example, if you are building on an existing data set for which a range of primary key values has already been assigned or reserved)

    • use a predefined sequence in an existing data model

  • @TableGenerator—If you use the @GeneratedValue annotation to specify a primary key generator of type TABLE, then you can use the @TableGenerator annotation to fine-tune this primary key generator to do the following:

    • change the name of the primary key generator's table, because the name is awkward, a reserved word, incompatible with a preexisting data model, or invalid as a table name in your database

    • change the allocation size to match your application requirements or database performance parameters

    • change the initial value to match an existing data model (for example, if you are building on an existing data set, for which a range of primary key values has already been assigned or reserved)

    • configure the primary key generator's table with a specific catalog or schema

    • configure a unique constraint on one or more columns of the primary key generator's table

For more information and examples of these annotations, see "Metadata for Object/Relational Mapping" in the JPA Specification.

Entities and Locking

By default, the EclipseLink persistence provider assumes that the application is responsible for data consistency.

You have the choice between optimistic and pessimistic locking. Oracle recommends using optimistic locking. For more information, see Descriptors and Locking

Oracle recommends that you use the @Version annotation to enable JPA-managed optimistic locking by specifying the version field or property of an entity class that serves as its optimistic lock value. When choosing a version field or property, ensure that the following is true:

  • there is only one version field or property per entity

  • you choose a property or field persisted to the primary table (see "Table Annotation" in the JPA Specification)

  • your application does not modify the version property or field

Note:

The field or property type must either be a numeric type (such as NumberlongintBigDecimal, and so on), or a java.sql.Timestamp. Oracle recommends using a numeric type.

The @Version annotation does not have attributes.

For more information, see the following:

For more information on the EclipseLink artifacts configured by JPA metadata, see Descriptors and Locking.

Extensible Entities

JPA entities and JAXB beans can be made extensible by adding or modifying mappings externally.

There is no need to modify the entity or bean source file nor do you have to redeploy the persistence unit.

Extensible entities are useful in a multi-tenant (or SaaS) architecture where a shared, generic application can be used by multiple clients (tenants). Tenants have private access to their own data, and to data shared with other tenants.

Using extensible entities, you can:

  • Build an application where some mappings are common to all users and some mappings are user-specific.

  • Add mappings to an application after it is made available to a customer (even post-deployment).

  • Use the same EntityManagerFactory interface to work with data after mappings have changed.

  • Provide an additional source of metadata to be used by an application.

Use the @VirtualAccessMethods annotation to specify that a JPA entity is extensible and use the @XmlVirtualAccessMethods annotation to specify that a JAXB bean is extensible. In both cases, you use virtual properties to specify external mappings. This allows you to modify the mappings without modifying source files and without redeploying the persistence unit.

For information on how to make JPA entities and JAXB beans extensible, see "Making JPA Entities and JAXB Beans Extensible" in Solutions Guide for EclipseLink.