【问题标题】:Does @ElementCollection imply orphanRemoval?@ElementCollection 是否暗示 orphanRemoval?
【发布时间】:2018-03-07 14:45:22
【问题描述】:

根据这篇文章Difference between @OneToMany and @ElementCollection?,我更喜欢@ElementCollection 用于可嵌入类型,@OneToMany 用于实体。但是使用@OneToMany 我可以额外设置选项orphanRemoval=true。我怎样才能用@ElementCollection 做到这一点?它暗示了吗?

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

    这是隐含的。删除拥有实体也会删除@ElementCollection 上的所有数据。如果Session 尚未关闭,将Collection 设置为null 或更改Collection 中的元素将导致更新。

    官方文档here是这样说的:

    2.8.1。集合作为值类型

    值和可嵌入类型集合具有类似的行为 简单的值类型,因为它们在 由持久对象引用并在发生时自动删除 未引用。如果一个集合从一个持久对象传递到 另一个,它的元素可能会从一个表移动到另一个表。
    ...
    对于值类型的集合,JPA 2.0 定义了 @ElementCollection 注解。值类型集合的生命周期完全是 由其所属实体控制。

    我运行了这三个测试来测试它:

      @Test
      public void selectStudentAndSetBooksCollectionToNull() {
        Student student = studentDao.getById(3L);
        List<String> books = student.getBooks();
    
        books.forEach(System.out::println);
    
        student.setBooks(null);
    
        em.flush(); // delete from student_book where student_id = ?
      }
    
      @Test
      public void selectStudentAndAddBookInCollection() {
        Student student = studentDao.getById(3L);
        List<String> books = student.getBooks();
    
        books.add("PHP Book");
    
        books.forEach(System.out::println);
    
        em.flush(); // insert into student_book(student_id, book) values(?, ?)
      }
    
      @Test
      public void selectStudentAndChangeCollection() {
        Student student = studentDao.getById(3L);
        List<String> newBooks = new ArrayList<>();
    
        newBooks.add("Rocket Engineering");
    
        newBooks.forEach(System.out::println);
    
        student.setBooks(newBooks);
    
        em.flush(); // delete from student_book where student_id = ?
        // insert into student_book(student_id, book) values(?, ?)
      } 
    

    这是Student 类:

    @Entity
    @Table(name = "student")
    public class Student {
    
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "student_id", nullable = false, insertable = false, updatable = false)
      private Long id;
    
      @Column(name = "name", nullable = false)
      private String name;
    
      @ElementCollection
      @CollectionTable(
          name = "student_books",
          joinColumns = @JoinColumn(name = "student_id", referencedColumnName = "student_id"))
      @Column(name = "book")
      private List<String> books = new ArrayList<>();
    
      // Getters & Setters
    
    }
    

    【讨论】:

    • 但这并不是 orphanRemoval 的全部内容。当然,如果您删除父级,子级将以级联方式删除,但是如果您只是失去对子级的引用(例如,将其设置为 null),从而使其不再可用怎么办?
    • 是的,@ElementCollection 字段隐含了Cascasde.ALL + orphanRemoval = true
    猜你喜欢
    • 2015-06-25
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 2011-03-17
    • 2012-10-09
    • 1970-01-01
    相关资源
    最近更新 更多