In this section we will look into how to map the different types of properties. All properties if mapped with annotation are by default persistent. This is different from when XML is used for mapping. In XML mapping, only the properties explicitly mapped are persistent.
Transient
If a property needs to be stopped from being persistent.
@Transient
public int getActive() {
return active;
}
Now this property does not becomes part of persistent mechanism. The property resides only in the Java layer.
Temporal
Allow to map java.util.Date and java.util.Calender. In SQL the date are differentiated by whether it's a date, time or a timestamp. Timestamp has both date and time. However in Java the date is always a timestamp. It has all the information. So we have to deal with this mismatch also.
//Options for TemporalType
// - DATE
// - TIME
// - TIMESTAMP
@Temporal(TemporalType.TIMESTAMP)
public Date getBirthDate() {
return birthDate;
}
Large Data
Large data is characterized by whether it is a binary large data (BLOB) or character larger date (CLOB)
- Blob - byte[], Byte[]
- Clob - char[], Character[]
BLOB and CLOB both are mapped with Lob annotation
@Lob
public byte[] getPicture() {
return picture;
}
Enumeration
Enumeration are type safe way of restricting the choice in Java. Let's say we have enum defined in Java as
public enum StudentType {
CURRENT,
ALUMNI
}
to specify the usage of this enum in entity
@Enumerated(EnumType.STRING)
public StudentType getStudentType() {
return studentType;
}
Enum Type can be String or Ordinal. If String is specified, in the database CURRENT or ALUMNI is stored. If ordinal is specified 0 or 1 is saved. If Enum Type is omitted ORDINAL is taken as default.
Derived Properties
Derived properties are useful to calculate formulas or derived values which is not stored in database but important for business purpose.
@org.hibernate.annotations.Formula("(MARKS/TOTAL_MARKS)*100")
public Long getPercentage() {
return percentage
}
The value is evaluated while fetching the entity so it might be outdated at other times. It's the responsibility of the developer to keep it updated.The property appears in the SELECT statement only and does not participates in INSERT or UPDATE statement.Even SQL expression can be passed to the underlying database so there is a chance to build database dependency.SQL functions including SQL subselects can be used.
Handling Generated Values
In DDL we define defaults to many values like SYSDATE for timestamp which means if we do not give value from Java it is automatically generated.After saving if we want to refresh the object in Java layer, we will have to call a refresh on the object. The other way is that we can tell Hibernate to refresh the value automatically after an insertion. Make sure that you have dynamicInsert set to false otherwise null value will be inserted into the database.
@Column(updatable= false, insertable = false)
@org.hibernate.annotations.Generated
(org.hibernate.annotations.GenerationTime.INSERT)
public Double getPendingAmount() {
return pendingAmount;
}
Embedded classes
Embedded classes are useful for bringing fine domain modeling. We have one table but more classes mapped to it to bring rich domain model. Though Student table contains all the details for Student and his address, we will map it to two classes.
Student Table
Student_Id
Name
City
Country
Let's have city and country mapped to a different class Address. We put Embeddable annotation on it to tell that it will be used as an embedded property in an entity class
@Embeddable
public class Address {
protected String city;
protected String country;
@Column(name = "ADD_CITY")
public String getCity() {
In the Student class
private Address address;
@Embedded
public Address getAddress() {
return address;
}
//Setter method
By default this will mapped to ADD_CITY column name as mapped in Address. To get it mapped to CITY column as in Student table, we ill have to override the column name.
@Embedded
@AttributeOverride (name= "city",column = @Column(name="CITY"))
public Address getAddress() {
return address;
}
Now in this case we can navigate to Address object by holding a reference of Student object. But it's not possible to navigate from Address object to Student object. To build the bi directional navigation in Address entity
In Address class
@org.hibernate.annotations.Parent
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
No comments:
Post a Comment