1.抽象基类
每个实体Bean都有一些类似的字段,例如id,version等,所以可以抽象出一个基类来。
package org.bnuitse.tms.model;
import java.io.Serializable;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
@MappedSuperclass
public abstract class AbstractEntityBean implements IEntityBean, Serializable {
private static final long serialVersionUID = 1L;
protected int id;
private int version;
public AbstractEntityBean() {
}
public void setId(int id) {
this.id = id;
}
@Version
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
@MappedSuperclass用于标识AbstractEntityBean中的数据字段也用于持久化。
IEntityBean是一个接口,用于会话Bean进行统一处理。见《教学管理系统-会话Bean》。
package org.bnuitse.tms.model;
public interface IEntityBean {
int getId();
}
2.具体类
具体类需要定义从接口继承来的抽象方法getId(),原因是每个具体类对应数据库的主键名称、产生方式可能不同,需要在getId()方法上用@Column进行标识。
一对多数据,例如classes和depts,如果想要处理简单些,可以用Hibernate的DELETE_ORPHAN进行标识,具体含义见Hibernate文档。
一对多数据提供了addXxx和removeXxx方法,为的是进行aspect编程,见《教学管理系统-面向方面的编程》。
一对多数据通常是延迟加载。可以在查询语句中使用fetch加载lazy data。为了使用方便,自定义一个annotation称为@EagerlyFetchQuery,在会话Bean中会查找它,执行里面定义的查询。
private static final long serialVersionUID字段需要定义,原因有二:一是如果一个类实现Serializable接口,推荐定义该字段;二是当aspectj织入代码产生新类时,如果没有定义该字段,会自动生成一个新的serialVersionUID值(见java.io),这样,UI从服务器端取出的数据和本地类的版本号不同,将产生异常。
package org.bnuitse.tms.model.security;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import org.bnuitse.tms.model.AbstractEntityBean;
import org.bnuitse.tms.model.EagerlyFetchQuery;
@Entity
@Table(name = "org_college")
@EagerlyFetchQuery("from College o left join fetch o.classes left join fetch o.depts where o.id = :id")
public class College extends AbstractEntityBean {
private static final long serialVersionUID = -8443100575405647610L;
private String name;
private List<CollegeClass> classes = new ArrayList<CollegeClass>();
private List<CollegeDept> depts = new ArrayList<CollegeDept>();
@Id
@Column(name="collegeId")
@TableGenerator(name = "CollegeGen", table = "pub_keygen", pkColumnName = "keyid", valueColumnName = "keyvalue", pkColumnValue = "College", allocationSize = 10, initialValue = 10000)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "CollegeGen")
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(mappedBy = "college", cascade = CascadeType.ALL)
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
public List<CollegeClass> getClasses() {
return classes;
}
public void setClasses(List<CollegeClass> classes) {
this.classes = classes;
}
public void addClass(CollegeClass collegeClass) {
collegeClass.setCollege(this);
this.classes.add(collegeClass);
}
public void removeClass(CollegeClass collegeClass) {
this.classes.remove(collegeClass);
}
@OneToMany(mappedBy = "college", cascade = CascadeType.ALL)
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
public List<CollegeDept> getDepts() {
return depts;
}
public void setDepts(List<CollegeDept> depts) {
this.depts = depts;
}
public void addDepartment(CollegeDept collegeDept) {
collegeDept.setCollege(this);
this.depts.add(collegeDept);
}
public void removeDepartment(CollegeDept collegeDept) {
this.depts.remove(collegeDept);
}
public String toString() {
return this.getId() + "-" + this.name;
}
}