在hibernate里面调用session的delete方法以后,无论这个被删除的对象有没有被人外键引用到,都可以被删除,并且此时的外键设为null,也就是说他会自动帮我们去查看他被谁引用到了。然后把引用全部去掉后,再把自己删掉。而在jpa里面,如果调用entitymanager.remove方法时,传进去的对象,有被外键引用到,则会失败。因为jpa里面的实现就是直接执行delete语句,也不管他有没有被外键引用,此时,当然会出错了。
测试时候使用的两个类分别如下:
举的例子是部门和员工的关系。一个部门可以有多个员工。然后把部门删掉的时候,员工的部门属性就为null了,不过,按照严谨来说,还是jpa的严谨一些。这样可以防止误操作,呵呵。
部门的实体对象
/*
* to change this template, choose tools | templates
* and open the template in the editor.
*/
package com.hadeslee.jpaentity;
import java.io.serializable;
import java.util.hashset;
import java.util.set;
import javax.persistence.entity;
import javax.persistence.generatedvalue;
import javax.persistence.generationtype;
import javax.persistence.id;
import javax.persistence.onetomany;
import javax.persistence.table;
/**
*
* @author hadeslee
*/
@entity
@table(name = "jpadepartment")
public class department implements serializable {
private static final long serialversionuid = 1l;
@id
@generatedvalue(strategy = generationtype.auto)
private long id;
@onetomany(mappedby = "department")
private set<person> persons = new hashset<person>();
private string deptname;
private string description;
public string getdeptname() {
return deptname;
}
public void setdeptname(string deptname) {
this.deptname = deptname;
}
public string getdescription() {
return description;
}
public void setdescription(string description) {
this.description = description;
}
public set<person> getpersons() {
return persons;
}
public void setpersons(set<person> persons) {
this.persons = persons;
}
public long getid() {
return id;
}
public void setid(long id) {
this.id = id;
}
@override
public int hashcode() {
int hash = 0;
hash = (id != null ? id.hashcode() : 0);
return hash;
}
@override
public boolean equals(object object) {
// todo: warning - this method won't work in the case the id fields are not set
if (!(object instanceof department)) {
return false;
}
department other = (department) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@override
public string tostring() {
return "com.hadeslee.jpaentity.department[id=" id "]";
}
}
人员的实体对象
/*
* to change this template, choose tools | templates
* and open the template in the editor.
*/
package com.hadeslee.jpaentity;
import java.io.serializable;
import javax.persistence.entity;
import javax.persistence.generatedvalue;
import javax.persistence.generationtype;
import javax.persistence.id;
import javax.persistence.manytoone;
import javax.persistence.table;
/**
*
* @author hadeslee
*/
@entity
@table(name = "jpaperson")
public class person implements serializable {
private static final long serialversionuid = 1l;
@id
@generatedvalue(strategy = generationtype.auto)
private integer id;
private string name;
private int age;
@manytoone
private department department;
public int getage() {
return age;
}
public void setage(int age) {
this.age = age;
}
public department getdepartment() {
return department;
}
public void setdepartment(department department) {
this.department = department;
}
public string getname() {
return name;
}
public void setname(string name) {
this.name = name;
}
public integer getid() {
return id;
}
public void setid(integer id) {
this.id = id;
}
@override
public int hashcode() {
int hash = 0;
hash = (id != null ? id.hashcode() : 0);
return hash;
}
@override
public boolean equals(object object) {
// todo: warning - this method won't work in the case the id fields are not set
if (!(object instanceof person)) {
return false;
}
person other = (person) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@override
public string tostring() {
return "com.hadeslee.jpaentity.person[id=" id "]";
}
}
由于jpa是不需要配置的,代码里面已经包括了注释,所以下面附上hibernate的映射文件,为了使数据库里面更清楚一些,所以两者使用的表不是同一张表,jpa的表是带jpa前缀的,用@table这个注释声明了这一点。
xml version="1.0" encoding="utf-8"?>
doctype hibernate-mapping public
"-//hibernate/hibernate mapping dtd 3.0//en"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hadeslee.jpaentity">
<class name="department" table="department">
<id name="id" column="departid" type="long">
<generator class="native"/>
id>
<property name="deptname"/>
<property name="description"/>
<set name="persons">
<key column="deptid"/>
<one-to-many class="person"/>
set>
class>
<class name="person" table="person">
<id name="id" column="personid" type="long">
<generator class="native"/>
id>
<property name="name"/>
<property name="age"/>
<many-to-one name="department" column="deptid" class="department"/>
class>
hibernate-mapping>
调用jpa的代码如下:
entitymanagerfactory emf = persistence.createentitymanagerfactory("testssh1pu2");
entitymanager em = emf.createentitymanager();
em.gettransaction().begin();
com.hadeslee.jpaentity.person p = new com.hadeslee.jpaentity.person();
p.setage(26);
p.setname("千里冰封");
com.hadeslee.jpaentity.department dept = em.find(com.hadeslee.jpaentity.department.class, long.valueof("3"));
system.out.println("找到的dept=" dept);
em.remove(dept);
em.gettransaction().commit();
调用hibernate的代码如下:
session session = hibernateutil.getsessionfactory().getcurrentsession();
session.gettransaction().begin();
department dept = (department) session.load(department.class, 2);
session.delete(dept);
session.gettransaction().commit();
最后发现是jpa是不能删除的,而hibernate这边的调用可以删除,一开始我还以为是toplink的实现问题,后来特意把实现改成hibernate的实现,也同样。所以有可能是jpa的要求必须得这样做,不能替我们自动完成一些东西,是利于安全。这可能就是标准和流行的差别吧。呵呵。
尽管千里冰封
依然拥有晴空
你我共同品味java的浓香.
posted on 2008-10-21 08:23
千里冰封 阅读(5968)
评论(6) 编辑 收藏 所属分类:
javaee