千里冰封
          JAVA 濃香四溢
          posts - 151,comments - 2801,trackbacks - 0
          在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.class2);
                  session.delete(dept);
                  session.getTransaction().commit();

          最后發現是JPA是不能刪除的,而hibernate這邊的調用可以刪除,一開始我還以為是toplink的實現問題,后來特意把實現改成hibernate的實現,也同樣。所以有可能是JPA的要求必須得這樣做,不能替我們自動完成一些東西,是利于安全。這可能就是標準和流行的差別吧。呵呵。






          盡管千里冰封
          依然擁有晴空

          你我共同品味JAVA的濃香.
          posted on 2008-10-21 08:23 千里冰封 閱讀(6060) 評論(6)  編輯  收藏 所屬分類: JAVAEE

          FeedBack:
          # re: JPA和hibernate對刪除操作的不同
          2008-10-21 08:44 | zd
          不錯  回復  更多評論
            
          # re: JPA和hibernate對刪除操作的不同
          2008-10-21 09:34 | attend
          從ORM的角度來說,我覺得hibernate的操作對點.員工和部門本來就是組合關系,員工離了部門也可以獨立存在。  回復  更多評論
            
          # re: JPA和hibernate對刪除操作的不同
          2008-10-21 09:42 | BeanSoft
          很好 到底是 Oracle 的人做的JPA參考實現 考慮到了壞數據的問題 如果引用一環套一環 Hibernate 那樣很容易造成大量不合要求的壞數據或者誤刪  回復  更多評論
            
          # re: JPA和hibernate對刪除操作的不同
          2008-10-21 21:21 | leekiang
          我用hibernate刪被外鍵引用的數據時都刪不掉,怎么你那里能刪掉?是由于hibernate配置不同造成的?  回復  更多評論
            
          # re: JPA和hibernate對刪除操作的不同
          2008-12-10 11:54 | 嗷嗷嗷
          樓上的問題是配置文件里沒配級聯刪除吧  回復  更多評論
            
          # re: JPA和hibernate對刪除操作的不同[未登錄]
          2016-04-21 23:24 | Rick
          呵呵  回復  更多評論
            
          主站蜘蛛池模板: 张掖市| 安阳县| 温泉县| 郴州市| 凌源市| 石棉县| 新昌县| 济南市| 洛扎县| 柞水县| 五原县| 商丘市| 邵阳市| 云阳县| 高陵县| 内江市| 同仁县| 昭通市| 吴忠市| 清水县| 南溪县| 安远县| 克什克腾旗| 峡江县| 阿巴嘎旗| 聂荣县| 灌南县| 邢台县| 卫辉市| 康乐县| 普兰店市| 临城县| 黄平县| 台东市| 孝感市| 尼木县| 额尔古纳市| 平阴县| 内乡县| 花垣县| 双桥区|