JPA和hibernate对删除操作的不同

在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 persons = new HashSet();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 getPersons() {return persons;}public void setPersons(Set persons) {this.persons = persons;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}@Overridepublic int hashCode() {int hash = 0;hash += (id != null ? id.hashCode() : 0);return hash;}@Overridepublic boolean equals(Object object) {// TODO: Warning - this method won't work in the case the id fields are not setif (!(object instanceof Department)) {return false;}Department ther = (Department) object;if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {return false;}return true;}@Overridepublic 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;@ManyToOneprivate 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;}@Overridepublic int hashCode() {int hash = 0;hash += (id != null ? id.hashCode() : 0);return hash;}@Overridepublic boolean equals(Object object) {// TODO: Warning - this method won't work in the case the id fields are not setif (!(object instanceof Person)) {return false;}Person ther = (Person) object;if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {return false;}return true;}@Overridepublic String toString() {return "com.hadeslee.jpaentity.Person[id=" + id + "] ";}}

由于JPA是不需要配置的,代码里面已经包括了注释,所以下面 附上Hibernate的映射文件,为了使数据库里面更清楚一些,所以两者使用的表 不是同一张表,JPA的表是带JPA前缀的,用@Table这个注释声明了这一点。

调用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的要求必须 得这样做,不能替我们自动完成一些东西,是利于安全。这可能就是标准和流行 的差别吧。呵呵。

饶人不是痴汉,痴汉不会饶人。

JPA和hibernate对删除操作的不同

相关文章:

你感兴趣的文章:

标签云: