Jpa/hibernate 为什么分离的实体部分合并?

问题描述 投票:0回答:1

当我从实体管理器获取实体然后将其分离并尝试删除相关实体时,数据库中没有对它们进行任何更改。换句话说,在实体管理器关闭(这是必需的)并再次打开后,仅合并对名称字段的更改,但不合并 B 列表。没有异常或其他错误或警告。 Hibernate日志只显示b_a数据库表中的选择,但不显示删除。

public class Main {

    public static void main(String[] args) {
        A a = getAByIdFromRepository(2);
        B b = a.getB().stream().filter(i -> i.getId() == 1).findFirst().orElse(null);
        a.remove(b);
        repositoryMerge(a);
    }

    public static A getAByIdFromRepository(int id) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistence_unit");
        EntityManager em = factory.createEntityManager();
        A a = em.find(A.class, id);
        em.close();
        factory.close();
        return a;
    }

    public static void repositoryMerge(A a) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistence_unit");
        EntityManager entityManager = factory.createEntityManager();
        entityManager.getTransaction().begin();
        entityManager.merge(a);
        entityManager.getTransaction().commit();
        entityManager.close();
        factory.close();
    }
}
@Entity
@Table(name = "a")
public class A implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "a_id")
    protected int id;
    @Column(name = "a_name")
    protected String name;
    @ManyToMany(mappedBy = "a", fetch = FetchType.EAGER)
    protected List<B> b;

   //getters setters etc.

    public void remove(B b) {
        this.getB().remove(b);
        b.getA().remove(this);
    }

}
@Entity
@Table(name = "b")
public class B implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "b_id")
    protected int id;
    @Column(name = "b_name")
    protected String name;
    @JoinTable(
            name = "b_a",
            joinColumns = @JoinColumn(name = "b_id"),
            inverseJoinColumns = @JoinColumn(name = "a_id"))
    @ManyToMany(fetch = FetchType.EAGER)
    protected List<A> a;

  //getters setters etc.


}

当获取、从实体中删除并合并时,通过一个打开的实体管理器进行,这是有效的:

        EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistence_unit");
        EntityManager entityManager = factory.createEntityManager();
        A a = entityManager.find(A.class, 2);
        B b = a.getB().stream().filter(i -> i.getId() == 1).findFirst().orElse(null);
        a.remove(b);
        entityManager.getTransaction().begin();
        entityManager.merge(a);
        entityManager.getTransaction().commit();
        entityManager.close();
        factory.close();
java hibernate jpa orm persistence
1个回答
0
投票

实体“A”不拥有 A.b ManyToMany 关系映射,因为您已将其标记为由 B.a 关系映射。这意味着更改只能从事物的 B 端获取 - 如果您需要从关系中删除“B”实例,则需要将 B 合并到上下文中。如果可能的话,您仍然应该合并 A,以使 A 的缓存副本与各种缓存策略中的数据库保持同步,但在您展示的简单测试中不太可能需要。

© www.soinside.com 2019 - 2024. All rights reserved.