<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Hibernate JPA 級聯類型 > 原文: [https://howtodoinjava.com/hibernate/hibernate-jpa-cascade-types/](https://howtodoinjava.com/hibernate/hibernate-jpa-cascade-types/) 我們已經在之前的教程中了解了 Hiberate 中的[**映射關聯實體**](//howtodoinjava.com/hibernate/how-to-define-association-mappings-between-hibernate-entities/ "How to Define Association Mappings between Hibernate Entities"),例如[**一對一映射**](//howtodoinjava.com/hibernate/hibernate-one-to-one-mapping-using-annotations/ "Hibernate one-to-one mapping using annotations")和[**一對多映射**](//howtodoinjava.com/hibernate/hibernate-one-to-many-mapping-using-annotations/ "Hibernate one-to-many mapping using annotations")。 每當要保存關系所有者實體時,我們都想保存映射的實體。 為此,我們使用了“`CascadeType`”屬性。 在此 **JPA 級聯類型**教程中,我們將通過`CascadeType`了解各種可用的級聯選項。 ## JPA 級聯類型如何工作? 在繼續之前,讓我們看一下如何在代碼中定義此級聯類型屬性。 讓我們舉個例子來更清楚地了解。 假設一個雇員可以有多個帳戶; 但一個帳戶只能與一名員工關聯。 為了清楚起見,讓我們以最少的信息創建實體。 **`EmployeeEntity.java`** ```java @Entity @Table(name = "Employee") public class EmployeeEntity implements Serializable { private static final long serialVersionUID = -1798070786993154676L; @Id @Column(name = "ID", unique = true, nullable = false) private Integer employeeId; @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100) private String firstName; @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100) private String lastName; @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name="EMPLOYEE_ID") private Set<AccountEntity> accounts; //Getters and Setters Ommited } ``` **`AccountEntity.java`** ```java @Entity @Table(name = "Account") public class AccountEntity implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "ID", unique = true, nullable = false) @GeneratedValue(strategy = GenerationType.SEQUENCE) private Integer accountId; @Column(name = "ACC_NO", unique = false, nullable = false, length = 100) private String accountNumber; @OneToOne (mappedBy="accounts", fetch = FetchType.LAZY) private EmployeeEntity employee; } ``` 查看上面`EmployeeEntity.java`源代碼中的粗體行。 它定義了“`cascade=CascadeType.ALL`”,從本質上講意味著`EmployeeEntity`上發生的任何更改也必須級聯到`AccountEntity`。 如果您保存員工,則所有關聯的帳戶也將保存到數據庫中。 如果刪除雇員,則與該雇員關聯的所有帳戶也將被刪除。 很簡單。 但是,如果我們只希望級聯僅保存操作而不刪除級聯,該怎么辦。 然后,我們需要使用以下代碼明確指定它。 ```java @OneToMany(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY) @JoinColumn(name="EMPLOYEE_ID") private Set<AccountEntity> accounts; ``` 現在,僅當使用員工實例調用`save()`或`persist()`方法時,才會保留帳戶。 如果在會話中調用任何其他方法,則該方法的效果不會影響/級聯到帳戶。 ## JPA 級聯類型 Java 持久化架構支持的級聯類型如下: 1. **`CascadeType.PERSIST`** :級聯類型`presist`表示`save()`或`persist()`操作級聯到相關實體。 2. **`CascadeType.MERGE`** :級聯類型`merge`表示在合并所有者實體時會合并相關實體。 3. **`CascadeType.REFRESH`** :級聯類型`refresh`對`refresh()`操作執行相同的操作。 4. **`CascadeType.REMOVE`** :級聯類型`remove`在刪除所有者實體時會刪除與此設置關聯的所有相關實體。 5. **`CascadeType.DETACH`** :如果發生“手動分離”,則級聯類型`detach`分離所有相關實體。 6. **`CascadeType.ALL`** :級聯類型`all`是上述所有級聯操作的簡寫。 > JPA 中沒有**默認級聯類型**。 默認情況下,沒有操作級聯。 級聯配置選項接受一個`CascadeTypes`數組。 因此,如我們的示例所示,為了在一對多關系的級聯操作中僅包括刷新和合并,您可能會看到以下內容: ```java @OneToMany(cascade={CascadeType.REFRESH, CascadeType.MERGE}, fetch = FetchType.LAZY) @JoinColumn(name="EMPLOYEE_ID") private Set<AccountEntity> accounts; ``` 上述級聯將導致僅合并和刷新帳戶集合。 ## Hiberate 級聯類型 現在,讓我們了解在哪種情況下使用 Hiberate 的 Hiberate 方式。 除了 JPA 提供的級聯類型之外,Hiberate 中還有一個級聯操作,它不是上面討論的正常設置的一部分,稱為“**孤例刪除**”。 將擁有的對象從其擁有的關系中刪除后,該對象將從數據庫中刪除。 讓我們看一個例子。 在我們的“雇員和帳戶”實體示例中,我對它們進行了如下更新,并在帳戶上提到“`orphanRemoval=true`”。 從本質上講,這意味著每當我要刪除“帳戶組中的帳戶”時(即我要刪除該帳戶與`Employee`之間的關系); 與數據庫上任何其他雇員(即孤例)沒有關聯的帳戶實體也應刪除。 **`EmployeeEntity.java`** ```java @Entity @Table(name = "Employee") public class EmployeeEntity implements Serializable { private static final long serialVersionUID = -1798070786993154676L; @Id @Column(name = "ID", unique = true, nullable = false) private Integer employeeId; @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100) private String firstName; @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100) private String lastName; @OneToMany(orphanRemoval = true, mappedBy = "employee") private Set<AccountEntity> accounts; } ``` **`AccountEntity.java`** ```java @Entity (name = "Account") @Table(name = "Account") public class AccountEntity implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "ID", unique = true, nullable = false) @GeneratedValue(strategy = GenerationType.SEQUENCE) private Integer accountId; @Column(name = "ACC_NO", unique = false, nullable = false, length = 100) private String accountNumber; @ManyToOne private EmployeeEntity employee; } ``` **`TestOrphanRemovalCascade.java`** ```java public class TestOrphanRemovalCascade { public static void main(String[] args) { setupTestData(); Session sessionOne = HibernateUtil.getSessionFactory().openSession(); org.hibernate.Transaction tx = sessionOne.beginTransaction(); //Load the employee in another session EmployeeEntity employee = (EmployeeEntity) sessionOne.load(EmployeeEntity.class, 1); //Verify there are 3 accounts System.out.println("Step 1 : " + employee.getAccounts().size()); //Remove an account from first position of collection employee.getAccounts().remove(employee.getAccounts().iterator().next()); //Verify there are 2 accounts in collection System.out.println("Step 2 : " + employee.getAccounts().size()); tx.commit(); sessionOne.close(); //In another session check the actual data in database Session sessionTwo = HibernateUtil.getSessionFactory().openSession(); sessionTwo.beginTransaction(); EmployeeEntity employee1 = (EmployeeEntity) sessionTwo.load(EmployeeEntity.class, 1); //Verify there are 2 accounts now associated with Employee System.out.println("Step 3 : " + employee1.getAccounts().size()); //Verify there are 2 accounts in Account table Query query = sessionTwo.createQuery("from Account a"); @SuppressWarnings("unchecked") List<AccountEntity> accounts = query.list(); System.out.println("Step 4 : " + accounts.size()); sessionTwo.close(); HibernateUtil.shutdown(); } private static void setupTestData(){ Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); //Create Employee EmployeeEntity emp = new EmployeeEntity(); emp.setEmployeeId(1); emp.setFirstName("Lokesh"); emp.setLastName("Gupta"); session.save(emp); //Create Account 1 AccountEntity acc1 = new AccountEntity(); acc1.setAccountId(1); acc1.setAccountNumber("11111111"); acc1.setEmployee(emp); session.save(acc1); //Create Account 2 AccountEntity acc2 = new AccountEntity(); acc2.setAccountId(2); acc2.setAccountNumber("2222222"); acc2.setEmployee(emp); session.save(acc2); //Create Account 3 AccountEntity acc3 = new AccountEntity(); acc3.setAccountId(3); acc3.setAccountNumber("33333333"); acc3.setEmployee(emp); session.save(acc3); session.getTransaction().commit(); session.close(); } } Output: Hibernate: insert into Employee (FIRST_NAME, LAST_NAME, ID) values (?, ?, ?) Hibernate: insert into Account (ACC_NO, employee_ID, ID) values (?, ?, ?) Hibernate: insert into Account (ACC_NO, employee_ID, ID) values (?, ?, ?) Hibernate: insert into Account (ACC_NO, employee_ID, ID) values (?, ?, ?) Hibernate: select employeeen0_.ID as ID1_1_0_, employeeen0_.FIRST_NAME as FIRST_NA2_1_0_, employeeen0_.LAST_NAME as LAST_NAM3_1_0_ from Employee employeeen0_ where employeeen0_.ID=? Hibernate: select accounts0_.employee_ID as employee3_1_0_, accounts0_.ID as ID1_0_0_, accounts0_.ID as ID1_0_1_, accounts0_.ACC_NO as ACC_NO2_0_1_, accounts0_.employee_ID as employee3_0_1_ from Account accounts0_ where accounts0_.employee_ID=? Step 1 : 3 Step 2 : 2 Hibernate: delete from Account where ID=? Hibernate: select employeeen0_.ID as ID1_1_0_, employeeen0_.FIRST_NAME as FIRST_NA2_1_0_, employeeen0_.LAST_NAME as LAST_NAM3_1_0_ from Employee employeeen0_ where employeeen0_.ID=? Hibernate: select accounts0_.employee_ID as employee3_1_0_, accounts0_.ID as ID1_0_0_, accounts0_.ID as ID1_0_1_, accounts0_.ACC_NO as ACC_NO2_0_1_, accounts0_.employee_ID as employee3_0_1_ from Account accounts0_ where accounts0_.employee_ID=? Step 3 : 2 Hibernate: select accountent0_.ID as ID1_0_, accountent0_.ACC_NO as ACC_NO2_0_, accountent0_.employee_ID as employee3_0_ from Account accountent0_ Step 4 : 2 ``` 這是從集合中刪除匹配項/不匹配項的好方法(即多對一或一對多關系)。 您只需從集合中刪除該項目,然后 Hiberate 即可為您處理其余所有事情。 它將檢查是否從任何地方引用了實體; 如果不是,它將從數據庫本身中刪除該實體。 讓我知道您對**Hiberate 5 級聯類型**或 **JPA 級聯類型**的想法和問題。 學習愉快! 閱讀更多: [有關級聯類型的 Oracle 博客](https://docs.oracle.com/cd/E19798-01/821-1841/bnbqm/index.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看