持久化类就是系统中有关业务实体的类(例如;电子商务系统中的
顾客类和订单类)。 并不是所有的持久化类的实例都处于持久化状态,
—— 可能是临时态(transient)或游离态(detached)。
如果遵守一些简单的约定,hibernate会工作的更好。 然而,这些
约定都不是强制的。事实上,Hibernate3 采取了遵守更少约定的策略。
你可以使用其他方式来表达一个实体域: 例如, 使用map树。
4.1 一个简单的POJO例子
大部分的java应用都使用一个扁平的持久化类。
package eg;
import java.util.Set;
import java.util.Date;
public class Cat {
private Long id; // identifier
private Date birthdate;
private Color color;
private char sex;
private float weight;
private int litterId;
private Cat mother;
private Set kittens = new HashSet();
private void setId(Long id) {
this.id=id;
}
public Long getId() {
return id;
}
void setBirthdate(Date date) {
birthdate = date;
}
public Date getBirthdate() {
return birthdate;
}
void setWeight(float weight) {
this.weight = weight;
}
public float getWeight() {
return weight;
}
public Color getColor() {
return color;
}
void setColor(Color color) {
this.color = color;
}
void setSex(char sex) {
this.sex=sex;
}
public char getSex() {
return sex;
}
void setLitterId(int id) {
this.litterId = id;
}
public int getLitterId() {
return litterId;
}
void setMother(Cat mother) {
this.mother = mother;
}
public Cat getMother() {
return mother;
}
void setKittens(Set kittens) {
this.kittens = kittens;
}
public Set getKittens() {
return kittens;
}
// addKitten not needed by Hibernate
public void addKitten(Cat kitten) {
kitten.setMother(this);
kitten.setLitterId( kittens.size() );
kittens.add(kitten);
}
}
这里主要有4个规则去遵守。
4.1.1 一个无参的构造方法
Cat 拥有一个无参的构造方法。 所有的持久化类都应该有一个默认的
无参的构造方法(可以不为public)以便hibernate调用Constructor.newInstance()
来对它进行实例化。我们强烈建议至少拥有一个包可见性的
默认构造方法。
4.1.2 提够一个标识符属性(可选)
Cat用户一个名为id的标识符。此属性映射到数据库表的主键列。
可以使用任何的基本类型或基本类型的包装类或 java.lang.String 或 java.util.Date来作为标识符。
(如过你的遗留数据库采用组合键, 你可以自定义一个class, class
属性为组合键)
标识符属性不是必须的,你可以不写(但不推荐)
我们建议你在持久化类中使用一致的标识符。我们更加建议
使用一个非null(不是基本类型)的类型。
4.1.3推荐使用非final的类(可选)
Hibernate的一个典型特征是代理,proxy依赖于非final 且 方法类型为
public的类。
你可以借助Hibernate持久化一个final类型的class, 但是, 此种情况你
便不能使用延迟加载,这也在一定程度上限制了你的程序。
你也应该避免使用final类型的方法。如果你使用了final类型的方法,
你必须设置lazy="false"。
4.1.4 声明持久化字段的set/get
Cat为所有的持久化字段声明了访问方法。
属性无需声明为public类型,Hibernate可以持久化任何一个具有默认
访问类型 或private或protected类型的属性。
4.2 实现继承
一个子类必须遵守第一和第二条规定。他从父类中继承标识符。
package eg;
public class DomesticCat extends Cat {
private String name;
public String getName() {
return name;
}
protected void setName(String name) {
this.name=name;
}
}
4.3 实现equals() 和hashCode()
如果你打算将持久化类的游离态的实例放到一个set中去时你必须复写equals()和
hashCode()方法。因为Hibernate只能在一个session内部保证java标识符和
数据库主键列相等。
推荐使用业务字段来实现equals()和hashCode(), 而不是主键。
public class Cat {
...
public boolean equals(Object other) {
if (this == other) return true;
if ( !(other instanceof Cat) ) return false;
final Cat cat = (Cat) other;
if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
if ( !cat.getMother().equals( getMother() ) ) return false;
return true;
}
public int hashCode() {
int result;
result = getMother().hashCode();
result = 29 * result + getLitterId();
return result;
}
}
4.4 动态模型
注意: 动态模型短时间内仍处于试验状态, 有可能会进行修改。
持久化的实体无需在运行期间被声明为POJO类型或一个javabean。Hibernate
支持动态模型和以DOM4j树的形式来展现实体。通过这种方法,你可以仅仅使用
映射文件来描述一个持久化类。
默认情况下,Hibernate工作在POJO模式下,你可以使用default_entity_mode
来设定一个默认模式。