![]() | |
| |
Persistent Fields and Properties
The persistent state of an entity is accessed by the persistence provider runtime either via JavaBeans style property accessors or via instance variables. A single access type (field or property access) applies to an entity hierarchy. When annotations are used, the placement of the mapping annotations on either the persistent fields or persistent properties of the entity class specifies the access type as being either field- or property-based access respectively.
If the entity has field-based access, the persistence provider runtime accesses instance variables DIRECTLY. All non-transient instance variables that are not annotated with the Transient annotation are persistent. When field-based access is used, the object/relational mapping annotations for the entity class annotate the instance variables.
@Entity
public class Operation implements Serializable {
@Id
private long id;
public long getId( ) {
return id;
}
public void setId(long id) {
this.id = id;
}
...
}
If the entity has property-based access, the persistence provider runtime accesses persistent state via the property ACCESSOR METHODS. All properties not annotated with the Transient annotation are persistent. The property accessor methods MUST be public or protected. When property-based access is used, the object/relational mapping annotations for the entity class annotate the getter property accessors. These annotations MUST NOT be applied to the setter methods.
@Entity
public class Operation implements Serializable {
private long id;
@Id
public long getId( ) {
return id;
}
public void setId(long id) {
this.id = id;
}
...
}
Mapping annotations CANNOT be applied to fields or properties that are transient or Transient.
The behavior is unspecified if mapping annotations are applied to both persistent fields and properties or if the XML descriptor specifies use of different access types within a class hierarchy.
It is required that the entity class follow the method signature conventions for JavaBeans read/write properties (as defined by the JavaBeans Introspector class) for persistent properties when persistent properties are used.
In this case, for every persistent property property of type Type of the entity, there is a getter method, getProperty, and setter method setProperty. For boolean properties, isProperty is an alternative name for the getter method.
For SINGLE-valued persistent properties, these method signatures are:
Type getProperty()
void setProperty(Type t)
COLLECTION-valued persistent fields and properties MUST be defined in terms of one of the following collection-valued interfaces regardless of whether the entity class otherwise adheres to the JavaBeans method conventions noted above and whether field or property-based access is used:
java.util.Collection
java.util.Set
java.util.List
java.util.Map
For COLLECTION-valued persistent properties, type Type MUST be one of these collection interface types in the method signatures above. Generic variants of these collection types may also be used (for example, Set<Order>).
In addition to returning and setting the persistent state of the instance, the property accessor methods may contain other business logic as well, for example, to perform validation. The persistence provider runtime executes this logic when property-based access is used.
Caution should be exercised in adding business logic to the accessor methods when property-based access is used. The order in which the persistence provider runtime calls these methods when loading or storing persistent state is NOT DEFINED. Logic contained in such methods therefore cannot rely upon a specific invocation order.
If property-based access is used and lazy fetching is specified, portable applications should not directly access the entity state underlying the property methods of managed instances until after it has been fetched by the persistence provider.
Runtime exceptions thrown by property accessor methods cause the current transaction to be rolled back. Exceptions thrown by such methods when used by the persistence runtime to load or store persistent state cause the persistence runtime to rollback the current transaction and to throw a PersistenceException that wraps the application exception.
Entity subclasses may override the property accessor methods. However, portable applications MUST NOT override the object/relational mapping metadata that applies to the persistent fields or properties of entity superclasses.
The persistent fields or properties of an entity MAY BE of the following types:
Java primitive types
java.lang.String
other Java serializable types (including wrappers of the primitive types, java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp, user-defined serializable types, byte[], Byte[], char[], and Character[])
enums
entity types and/or collections of entity types
embeddable classes
Example:
@Entity
public class Customer implements Serializable {
private Long id;
private String name;
private Address address;
private Collection<Order> orders = new HashSet();
private Set<PhoneNumber> phones = new HashSet();
// No-arg constructor
public Customer() {}
@Id // property access is used
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@OneToMany
public Collection<Order> getOrders() {
return orders;
}
public void setOrders(Collection<Order> orders) {
this.orders = orders;
}
@ManyToMany
public Set<PhoneNumber> getPhones() {
return phones;
}
public void setPhones(Set<PhoneNumber> phones) {
this.phones = phones;
}
// Business method to add a phone number to the customer
public void addPhone(PhoneNumber phone) {
this.getPhones().add(phone);
// Update the phone entity instance to refer to this customer
phone.addCustomer(this);
}
}
Embeddable Classes
An entity may use other fine-grained classes to represent entity state. Instances of these classes, unlike entity instances themselves, do not have persistent identity. Instead, they exist only as embedded objects of the entity to which they belong. Such embedded objects belong strictly to their owning entity, and are not sharable across persistent entities. Attempting to share an embedded object across entities has undefined semantics. Because these objects have no persistent identity, they are typically mapped together with the entity instance to which they belong.
Embeddable classes must adhere to the requirements specified in the Requirements on the Entity Class section for entities with the exception that embeddable classes are NOT annotated as Entity. Embeddable classes MUST be annotated as Embeddable or denoted in the XML descriptor as such. The access type for an embedded object is determined by the access type of the entity in which it is embedded. Support for only one level of embedding is required by EJB 3.0 specification.
Embeddable Annotation
The Embeddable annotation is used to specify a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity. Each of the persistent properties or fields of the embedded object is mapped to the database table for the entity. Only Basic, Column, Lob, Temporal, and Enumerated mapping annotations may portably be used to map the persistent fields or properties of classes annotated as Embeddable.
@Target({TYPE}) @Retention(RUNTIME)
public @interface Embeddable {
}
Example:
@Embeddable
public class EmploymentPeriod {
java.util.Date startDate;
java.util.Date endDate;
...
}
Embedded Annotation
The Embedded annotation is used to specify a persistent field or property of an entity whose value is an instance of an embeddable class.
The AttributeOverride and/or AttributeOverrides annotations may be used to override the column mappings declared within the embeddable class, which are mapped to the entity table.
Implementations are NOT required to support embedded objects that are mapped across more than one table (e.g., split across primary and secondary tables or multiple secondary tables).
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Embedded {}
Example below shows how to use this annotation to specify that @Embeddable class EmploymentPeriod may be embedded in the entity class:
@Entity
public class Employee implements Serializable {
...
@Embedded
@AttributeOverrides({
@AttributeOverride(name="startDate", column=@Column("EMP_START")),
@AttributeOverride(name="endDate", column=@Column("EMP_END"))
})
public EmploymentPeriod getEmploymentPeriod() {
...
}
...
}
|
|
|
|
Hosting provided by PerfoHost: KVM VPS. Unix VPS. Windows VPS. VPN. Domains. Dedicated servers. Colocation.