移除JPQL中非所有者关系也会移除关系。

huangapple go评论62阅读模式
英文:

Removing Non-Owner Of relation with JPQL removes relation too

问题

entityManager.remove() VS JPQL DELETE Query

我知道关系的一侧是所有者,而另一侧,用mapped by标记的一侧是非所有者。

关系在数据库中以所有者的持久性保存,并随着其移除而移除。
我知道移除非所有者一侧不会删除关系。
参见此链接

到目前为止都很好。

根据我的经验,使用JPQL查询来删除非所有者一侧的关系也会移除关系。对我来说不太清楚为什么!? 有没有令人信服的解释?

下面的代码片段显示了我用概念进行测试的测试案例:

非所有者

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String title;

    @ManyToMany(mappedBy = "books")
    private Set<Author> authors;
}

所有者:

@Entity
public class Author {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToMany
    private Set<Book> books;
}

测试1

public void persistingRelationOwnerPersistsRelationSuccessfully(){
    Book book = new Book("nonOwner");
    entityManager.persist(book);

    Author author = new Author("owner", new HashSet<>(Arrays.asList(book)));
    entityManager.persist(author);
    entityManager.flush();
}

日志:

Hibernate: insert into book (title, id) values (?, ?)
Hibernate: insert into author (name, id) values (?, ?)
Hibernate: insert into author_books (authors_id, books_id) values (?, ?)

测试2

public void removingRelationOwnerRemovesRelationSuccessfully(){
    // 持久化图书和作者

    entityManager.remove(author);
    entityManager.flush();
}

日志:

Hibernate: insert into book (title, id) values (?, ?)
Hibernate: insert into author (name, id) values (?, ?)
Hibernate: insert into author_books (authors_id, books_id) values (?, ?)
Hibernate: delete from author_books where authors_id=?
Hibernate: delete from author where id=?

测试3

public void removingNonOwnerWillThrowException(){
    // 持久化图书和作者

    entityManager.remove(book);
    entityManager.flush();
}

日志:(如预期)

Hibernate: insert into book (title, id) values (?, ?)
Hibernate: insert into author (name, id) values (?, ?)
Hibernate: insert into author_books (authors_id, books_id) values (?, ?)
Hibernate: delete from book where id=?
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement

测试4

public void removingNonOwnerWithQueryWillRemoveRelation(){
    // 持久化图书和作者

    Query query = entityManager.createQuery("delete from Book b where b.title = 'nonOwner'");
    System.out.println("affectedRows = " + query.executeUpdate());
}

日志:(意外的行为)

Hibernate: insert into book (title, id) values (?, ?)
Hibernate: insert into author (name, id) values (?, ?)
Hibernate: insert into author_books (authors_id, books_id) values (?, ?)
Hibernate: delete from author_books where (books_id) in (select id from book where title='nonOwner')
Hibernate: delete from book where title='nonOwner'
affectedRows = 1
英文:

entityManager.remove() VS JPQL DELETE Query

I know that one side of relation is owner and the other side, marked with mapped by, is non-owner.

Relation is saved in Database with persistence of owner and removed with removal of it.
I know that removal of non-owner side will not erase relation.
see this link

So far so good.

In my experience, removal on non-owner with JPQL query, removes relation too. It's not clear for me why!? Is there any persuasive explanation?

Code snippets below show my test cases with concept:

Non-Owner

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String title;

    @ManyToMany(mappedBy = "books")
    private Set<Author> authors;
}

Owner:

@Entity
public class Author {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToMany
    private Set<Book> books;
}

Test 1

public void persistingRelationOwnerPersistsRelationSuccessfully(){
    Book book = new Book("nonOwner");
    entityManager.persist(book);

    Author author = new Author("owner", new HashSet<>(Arrays.asList(book)));
    entityManager.persist(author);
    entityManager.flush();
}

Log:

Hibernate: insert into book (title, id) values (?, ?)
Hibernate: insert into author (name, id) values (?, ?)
Hibernate: insert into author_books (authors_id, books_id) values (?, ?)

Test 2

public void removingRelationOwnerRemovesRelationSuccessfully(){
    //persist book and author

    entityManager.remove(author);
    entityManager.flush();
}

Log:

Hibernate: insert into book (title, id) values (?, ?)
Hibernate: insert into author (name, id) values (?, ?)
Hibernate: insert into author_books (authors_id, books_id) values (?, ?)
Hibernate: delete from author_books where authors_id=?
Hibernate: delete from author where id=?

Test 3

public void removingNonOwnerWillThrowException(){
    //persist book and author

    entityManager.remove(book);
    entityManager.flush();
}

Log: (As Expected)

Hibernate: insert into book (title, id) values (?, ?)
Hibernate: insert into author (name, id) values (?, ?)
Hibernate: insert into author_books (authors_id, books_id) values (?, ?)
Hibernate: delete from book where id=?
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement

Test 4

public void removingNonOwnerWithQueryWillRemoveRelation(){
    //persist book and author

    Query query = entityManager.createQuery("delete from Book b where b.title = 'nonOwner'");
    System.out.println("affectedRows = " + query.executeUpdate());
}

Log: (Unexpected behavior)

Hibernate: insert into book (title, id) values (?, ?)
Hibernate: insert into author (name, id) values (?, ?)
Hibernate: insert into author_books (authors_id, books_id) values (?, ?)
Hibernate: delete from author_books where (books_id) in (select id from book where title='nonOwner')
Hibernate: delete from book where title='nonOwner'
affectedRows = 1

答案1

得分: 1

这可能是一个错误,因为这应该取决于 Book#authors 关联的级联设置,该设置可能会在删除 DML 语句中被忽略。您应该使用一个可重现的示例在 https://hibernate.atlassian.net/ 上记录此问题。

英文:

This might be a bug because this should depend on the cascading setting of the Book#authors association which might be ignored for a delete DML statement. You should log an issue with a reproducer https://hibernate.atlassian.net/

huangapple
  • 本文由 发表于 2020年10月3日 04:15:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/64177739.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定