注册
 找回密码
 注册
江西广告网
查看: 462|回复: 0
打印 上一主题 下一主题

JPA和hibernate对删除操作的不同

[复制链接]

该用户从未签到

1
跳转到指定楼层
发表于 2009-3-17 08:14:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册

x
在hibernate里面调用session的delete方法以后,无论这个被删除的对象有没有被人外键引用到,都可以被删除,并且此时的外键设为null,也就是说他会自动帮我们去查看他被谁引用到了。然后把引用全部去掉后,再把自己删掉。而在JPA里面,如果调用EntityManager.remove方法时,传进去的对象,有被外键引用到,则会失败。因为JPA里面的实现就是直接执行delete语句,也不管他有没有被外键引用,此时,当然会出错了。 测试时候使用的两个类分别如下: 举的例子是部门和员工的关系。一个部门可以有多个员工。然后把部门删掉的时候,员工的部门属性就为null了,不过,按照严谨来说,还是JPA的严谨一些。这样可以防止误操作,呵呵。 部门的实体对象 Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->/* * 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<erson> persons = new HashSet<erson>(); 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<erson> 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 "]"; } } 人员的实体对象 Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->/* * 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 "]"; } } [1] [2] 由于JPA是不需要配置的,代码里面已经包括了注释,所以下面附上Hibernate的映射文件,为了使数据库里面更清楚一些,所以两者使用的表不是同一张表,JPA的表是带JPA前缀的,用@Table这个注释声明了这一点。 Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><?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的代码如下: Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --> 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的代码如下: Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->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的要求必须得这样做,不能替我们自动完成一些东西,是利于安全。这可能就是标准和流行的差别吧。呵呵。 上一页 [1] [2]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表