Java Persistence annotations may be applied at three different levels: at the class, method, and field levels.



Accessing Entity State



Field Access

Using Field Access

@Entity
public class Employee {
@Id private int id;
private String name;
private long salary;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public long getSalary() { return salary; }
public void setSalary(long salary) { this. salary = salary; }

}

Property Access



The mapping annotations for a property must be on the getter method


Using Property Access

@Entity
public class Employee {
private int id;
private String name;

private long wage;
@Id public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public long getSalary() { return wage; }
public void setSalary(long salary) { this.wage = salary; }

}


Mapping to a Table



The @Entity and @Id annotations need to be specified to create and map an entity to a database table.
We do this by annotating the entity class with the @Table annotation and by including the name of the table using the name element. Many databases have terse names for tables.



Overriding the Default Table Name




@Entity
@Table(name="EMP")
public class Employee { ... }



The schema name is commonly used to differentiate one set of tables from another and is indicated by using the schema element.
Setting a Schema


@Entity
@Table(name="EMP", schema="HR")
public class Employee { ... }



Some databases support the notion of a catalog. For these databases, the catalog element of the @Table annotation may be specified
Setting a Catalog


@Entity
@Table(name="EMP", catalog="HR")
public class Employee { ... }




Mapping Simple Types


Simple Java types are mapped as part of the immediate state of an entity in its fields or properties.

The list of persistable types is quite lengthy and includes pretty much every type that you
would want to persist. They are


• Primitive Java types: byte, int, short, long, boolean, char, float, double
• Wrapper classes of primitive Java types: Byte, Integer, Short, Long, Boolean,
Character, Float, Double
• Byte and character array types: byte[], Byte[], char[], Character[]
• Large numeric types: java.math.BigInteger, java.math.BigDecimal
• Strings: java.lang.String
• Java temporal types: java.util.Date, java.util.Calendar
• JDBC temporal types: java.sql.Date, java.sql.Time, java.sql.Timestamp
• Enumerated types: Any system or user-defined enumerated type
• Serializable objects: Any system or user-defined serializable type


Column Mappings

Mapping Attributes to Columns

@Entity
public class Employee {
@Id
@Column(name="EMP_ID")
private int id;
private String name;
@Column(name="SAL")
private long salary;
@Column(name="COMM")
private String comments;
// ...

}

EMPLOYEE entity table





Lazy Fetching



There are many names for this kind of feature, including lazy loading, deferred loading, lazy fetching, on-demand fetching, just-in-time reading, indirection, and others. They all mean pretty much the same thing,
which is just that some data may not be loaded when the object is initially read from the database but will be fetched only when it is referenced or accessed.
The fetch type of a basic mapping can be configured to be lazily or eagerly loaded by specifying the fetch element in the corresponding @Basic annotation.
The FetchType enumerated type defines the values for this element, which may be either EAGER or LAZY
The default is to eagerly load all basic mappings

Lazy Field Loading

@Entity
public class Employee {
// ...
@Basic(fetch=FetchType.LAZY)
@Column(name="COMM")
private String comments;
// ...
}

Large Objects



A common database term for a character or byte-based object that can be very large (up to the gigabyte range) is large object, or LOB for short
The @Lob annotation acts as the marker annotation to fulfill this purpose and may appear in conjunction with the @Basic annotation, or it may appear when @Basic is absent and implicitly assumed to be on the mapping.
LOBs come in two flavors in the database: character large objects, called CLOBs, and binary large objects, or BLOBs.
The Java types mapped to BLOB columns are byte[], Byte[], and Serializable types, while char[], Character[], and String objects are mapped to CLOB columns.

Mapping a BLOB Column

@Entity
public class Employee {
@Id
private int id;
@Basic(fetch=FetchType.LAZY)
@Lob @Column(name="PIC")
private byte[] picture;
// ...
}

Enumerated Types

Interpreting the values as ordinals is the default way that providers will map enumerated types to the database, and the provider will assume that the database column is an integer type.

Consider the following enumerated type:

public enum EmployeeType {
FULL_TIME_EMPLOYEE,
PART_TIME_EMPLOYEE,
CONTRACT_EMPLOYEE
}

The ordinals assigned to the values of this enumerated type at compile time would be 0 for FULL_TIME_EMPLOYEE, 1 for PART_TIME_EMPLOYEE, and 2 for CONTRACT_EMPLOYEE.

Mapping an Enumerated Type Using Ordinals

@Entity
public class Employee {
@Id private int id;
private EmployeeType type;
// ...
}

The @Enumerated annotation actually allows an EnumType to be specified, and the
EnumType is itself an enumerated type that defines values of ORDINAL and STRING

Since the default value of @Enumerated is ORDINAL, specifying @Enumerated(ORDINAL) is useful only when you want to make this mapping explicit.

Mapping an Enumerated Type Using Strings

@Entity
public class Employee {
@Id
private int id;
@Enumerated(EnumType.STRING)
private EmployeeType type;
// ...
}

Temporal Types

Temporal types are the set of time-based types that may be used in persistent state mappings. The list of supported temporal types includes the three java.sql types java.sql.Date, java.sql.Time, and java.sql.Timestamp, and it includes the two java.util types java.util.Date and java.util.Calendar.

Mapping Temporal Types

@Entity
public class Employee {
@Id
private int id;
@Temporal(TemporalType.DATE)
private Calendar dob;
@Temporal(TemporalType.DATE)
@Column(name="S_DATE")
private Date startDate;
// ...
}

Transient State

Attributes that are part of a persistent entity but not intended to be persistent can either be modified with the transient modifier in Java or be annotated with the @Transient annotation

Transient fields are used for various reasons. One might be when you want to cache some
in-memory state that you don’t want to have to recompute, rediscover, or reinitialize

Using a Transient Field

@Entity
public class Employee {
@Id private int id;
private String name;
private long salary;
transient private String translatedName;
// ...
public String toString() {
if (translatedName == null) {
translatedName =
ResourceBundle.getBundle("EmpResources").getString("Employee");
}
return translatedName + ": " id + " " + name;
}
}


Mapping the Primary Key

Every entity that is mapped to a relational database must have a mapping to a primary key in the table.

Except for its special significance in designating the mapping to the primary key column,
an id mapping is almost the same as the basic mapping. Another difference is that id mappings are generally restricted to the following types:

• Primitive Java types: byte, int, short, long, char
• Wrapper classes of primitive Java types: Byte, Integer, Short, Long, Character
• Arrays of primitive or wrapper types: Byte, Integer, Short, Long, Character
• Strings: java.lang.String
• Large numeric types: java.math.BigInteger
• Temporal types: java.util.Date, java.sql.Date

Floating point types like float and double are permitted

the @Column annotation may be used to override the column name that the id attribute is
mapped to.

Identifier Generation

Sometimes applications do not want to be bothered with trying to define and ensure uniqueness in some aspect of their domain model and are content to let the identifier values be automatically generated for them. This is called id generation and is specified by the @GeneratedValue annotation.

When id generation is enabled, the persistence provider will generate an identifier value
for every entity instance of that type. Once the identifier value is obtained, the provider will insert it into the newly persisted entity; however, depending upon the way it is generated, it may not actually be present in the object until the entity has been inserted in the database.

Applications can choose one of four different id generation strategies by specifying a strategy in the strategy element. The value may be any one of AUTO, TABLE, SEQUENCE, or IDENTITY enumerated values of the GenerationType enumerated type.


Automatic Id Generation

If an application does not care what kind of generation is used by the provider but wants generation to occur, then it can specify a strategy of AUTO. This means that the provider will use whatever strategy it wants to generate identifiers.

Using Auto Id Generation
@Entity
public class Employee {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;
// ...

}

Id Generation Using a Table

The easiest way to use a table to generate identifiers is to simply specify the generation strategy to be TABLE in the strategy element:

@Id GeneratedValue(strategy=GenerationType.TABLE)

private int id;

We can define one by using a @TableGenerator annotation and then refer to it by name in the @GeneratedValue annotation:

@TableGenerator(name="Emp_Gen")
@Id @GeneratedValue(generator="Emp_Gen")

private int id;

A further qualifying approach would be to specify the table details, as in the following:

@TableGenerator(name="Emp_Gen",
table="ID_GEN",
pkColumnName="GEN_NAME",

valueColumnName="GEN_VAL")

The example shows an Address id generator named “Address_Gen” but then defines the value stored in the table for Address id generation as “Addr_Gen”. The generator also sets the initial value to 10000 and the allocation size to 100.

@TableGenerator(name="Address_Gen",
table="ID_GEN",
pkColumnName="GEN_NAME",
valueColumnName="GEN_VAL",
pkColumnValue="Addr_Gen",
initialValue=10000,
allocationSize=100)
@Id @GeneratedValue(generator="Address_Gen")
private int id;

Id Generation Using a Database Sequence

Many databases support an internal mechanism for id generation called sequences. A database sequence may be used to generate identifiers when the underlying database supports them.

The safer route would be to define a named sequence generator and refer to it in the @GeneratedValue annotation:

@SequenceGenerator(name="Emp_Gen", sequenceName="Emp_Seq")
@Id @GeneratedValue(generator="Emp_Gen")
private int getId;

Id Generation Using Database Identity

Some databases support a primary key identity column sometimes referred to as an autonumber column. Whenever a row is inserted into the table, then the identity column will get a unique identifier assigned to it. This can be used to generate the identifiers for objects, but once again is available only when the underlying database supports it.

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;

Leave a Reply

Subscribe to Posts | Subscribe to Comments

About This Site

Howdy! My name is Suersh Rohan and I am the developer and maintainer of this blog. It mainly consists of my thoughts and opinions on the technologies I learn,use and develop with.

Blog Archive

Powered by Blogger.

- Copyright © My Code Snapshots -Metrominimalist- Powered by Blogger - Designed by Suresh Rohan -