当我从实体管理器获取实体然后将其分离并尝试删除相关实体时,数据库中没有对它们进行任何更改。换句话说,在实体管理器关闭(这是必需的)并再次打开后,仅合并对名称字段的更改,但不合并 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();
实体“A”不拥有 A.b ManyToMany 关系映射,因为您已将其标记为由 B.a 关系映射。这意味着更改只能从事物的 B 端获取 - 如果您需要从关系中删除“B”实例,则需要将 B 合并到上下文中。如果可能的话,您仍然应该合并 A,以使 A 的缓存副本与各种缓存策略中的数据库保持同步,但在您展示的简单测试中不太可能需要。