Java JPA flush()不会在一对多关系中更新数据库?

时间:2016-01-24 02:56:00

标签: java jpa flush

所以我有一个Person类,它与Address类有一对多的关系(不是真的在我的代码中,但它类似于这样,只是为了让它更容易)。

我正在尝试将null设置为地址然后刷新它然后重新插入新地址但它将无法工作,因为地址表中可能存在重复键,即使我将地址设置为null然后刷新它。

我需要首先删除每个地址,然后将它们设置为null然后刷新。

-------------------------------------------------------------
// 1, this won't work, duplicate key exception when committing in Address table if there is a same address in newAddress with address in this person addresses

em.getTransaction().begin();
person.setAddresses(null);
em.flush();

// print the address, count is still the same with before depends on how many address this person has

String query = "SELECT P.addresses FROM Person P WHERE P = :pr"; 
ObservableList<Address> addresses= FXCollections.observableArrayList(
                                          em.createQuery(query, Address.class)
                                            .setParameter("pr", person)
                                            .getResultList());
System.out.println("COUNT: " + addresses.size() +  " name: " +  addresses.get(0).getName());  

person.setAddresses(newAddresses);
em.commit();             // exception

-----------------------------------------------------------------------

// 2, this works

em.getTransaction().begin();
for(Address a : person.getAddresses() {
em.remove(a);
}
person.setAddresses(null);
em.flush();

// print the address, count is still one and its null

String query = "SELECT P.addresses FROM Person P WHERE P = :pr"; 
ObservableList<Address> addresses= FXCollections.observableArrayList(
                                          em.createQuery(query, Address.class)
                                            .setParameter("pr", person)
                                            .getResultList());
System.out.println("COUNT: " + addresses.size() ); 
em.commit();         // fine

---------------------------------------------------------------------

1 个答案:

答案 0 :(得分:0)

一对多关系由业主方控制,在您的情况下是地址。因此,您必须在地址中设置/删除关系。

Person.setAddresses对JPA没有任何影响,正确的方法是遍历地址并设置address.person = null或完全删除地址。其余的应该遵循。