2016-07-29 108 views
0

我有兩個實體,OffreOffreCompetence和跟隨它們之間的關係:更新與另一個實體關係的實體春天

@OneToMany(mappedBy="offre",cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
     private Collection<OffreCompetence> offreCompetences; 

所以每個Offre實體有很多OffreCompetence實體。

假設我有一個「Offre」如下:

{ 
     "codeOffre": 144, 
     "titre": "Testable 999", 
      "offreCompetences": [ 
    { 
     "codeOffreCompetence": 93, 
     "niveauRequis": "77", 
     "competence": { 
     "codeCompetence": 17, 
     "titre": "Administrateur Mainframe IBM", 
     "activated": true 
     } 
    }, 
    { 
     "codeOffreCompetence": 94, 
     "niveauRequis": "88", 
     "competence": { 
     "codeCompetence": 18, 
     "titre": "Administrateur Autres Systèmes", 
     "activated": true 
     } 
    }, 
    { 
     "codeOffreCompetence": 95, 
     "niveauRequis": "99", 
     "competence": { 
     "codeCompetence": 19, 
     "titre": "Concepteur UML, Merise, ...", 
     "activated": true 
     } 
    }, 
    { 
     "codeOffreCompetence": 96, 
     "niveauRequis": "88", 
     "competence": { 
     "codeCompetence": 18, 
     "titre": "Administrateur Autres Systèmes", 
     "activated": true 
     } 
    }, 
    { 
     "codeOffreCompetence": 97, 
     "niveauRequis": "99", 
     "competence": { 
     "codeCompetence": 17, 
     "titre": "Administrateur Mainframe IBM", 
     "activated": true 
     } 
    } 
    ], 
     "ville": { 
      "codeVille": 2 
     }, 
     "typeContrat": { 
      "codeTypeContrat": 3 
     } 
     } 

然後我想更新這個Offre,所以我稱之爲put方法這需要一個「Offre」作爲PARAM,則此方法將調用業務代碼來更新這個「Offre」,這是更新這個實體的方法:

public Offre updateOffre(Offre offre) { 

    for(OffreCompetence offreCompetence : offre.getOffreCompetences()) { 
     offreCompetence.setOffre(offre); 
    } 
    return offreRepository.saveAndFlush(offre); 
} 

所以我會送這個新的JSON,我刪除了一些「OffreCompetence」關係,我添加了一個新的:

{ 
    "codeOffre": 144, 
    "titre": "Testable 999", 
    "offreCompetences": [ 
     { 
     "codeOffreCompetence": 96, 
     "niveauRequis": "88", 
     "competence": { 
      "codeCompetence": 18 
     } 
     }, 
     { 
     "niveauRequis": "5", 
     "competence": { 
      "codeCompetence": 17 
     } 
     } 
    ], 
    "ville": { 
     "codeVille": 2 
    }, 
    "typeContrat": { 
     "codeTypeContrat": 3 
    } 
    } 

這裏的問題是,它將這兩個關係作爲新關係添加到舊關係中,因爲您可以看到我刪除了一個並更新了一個並刪除了一個,所以更新的Offre應該只包含關係I'已發送。

我在設置新關係之前想過使用服務方法刪除舊關係,該方法搜索與Offre的所有關係並刪除它們,然後添加我用Offre對象發送的關係,但是我希望這自動完成。

有什麼建議嗎?

非常感謝。

編輯:

似乎增加了新的關係和更新他們的工作,但刪除它不工作。

+0

你試過hibernate merge嗎? – kukkuz

回答

0

盡我所能得到給定的分離對象(您JSON Offre和樹OffreCompetence是下面。我的情況是2個實體,OrderOrderLine,映射你的方式相同。

Order.java

@Entity 
@Table(name = "ORDERS") 
public class Order implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ORDER_ID") 
    private Long id; 

    // ... basic attributes 

    // same mapping as in your use case 
    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private Set<OrderLine> orderLines; 

    /* getters and setters */ 

} 

OrderLine.java

@Entity 
@Table(name = "ORDER_LINES") 
public class OrderLine implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ORDER_LINE_ID") 
    private Long id; 

    // ... basic attributes 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ORDER_ID") 
    private Order order; 

    /* getters and setters */ 

    /* equals and hashCode */ 

} 

堅持根節點及其子做升IKE在此:

@Override 
public Order findWithReference(String reference) { 
    List<Order> list = em.createQuery("SELECT o FROM Order o WHERE o.reference = :reference") 
      .setParameter("reference", reference).getResultList(); 
    if (list.isEmpty()) { 
     return null; 
    } else if (list.size() == 1) { 
     return list.get(0); 
    } else { 
     throw new IllegalStateException(String.format("The reference '%s' should uniquely identify an order.", reference)); 
    } 
} 

@Override 
public Order save(Order order) { 
    Order managed = findWithReference(order.getReference()); 
    if (managed == null) { 
     em.persist(order); 
     return order; 
    } else { 
     // remove obsolete children and children existing both in detached and managed entity 
     for (Iterator<OrderLine> iter = managed.getOrderLines().iterator(); iter.hasNext();) { 
      OrderLine managedOrderLine = iter.next(); 
      if (!order.getOrderLines().contains(managedOrderLine)) { 
       iter.remove(); 
       em.remove(managedOrderLine); 
      } else { 
       order.getOrderLines().remove(managedOrderLine); 
      } 
     } 
     order.setId(managed.getId()); 
     return em.merge(order); 
    } 
} 

的合併獲得令人滿意的效果的技巧是從分離實例中刪除從管理實體過時的孩子和已經存在的兒童。爲了與孩子們相配,我實施了equalshashCodeOrderLine,總體而言這種方法並不那麼難看。