2012-05-03 1 views
0

J'ai rencontré un bogue avec jpa et hibernate. J'ai une classe de facturation avec l'annotation suivante:Hibernate mettant à jour une collection à plusieurs quand l'objet a été retiré de la collection

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) 
@JoinColumn(name="ch1_id", referencedColumnName="id") 
private List<BillingItem>billingItems = new ArrayList<BillingItem>(); 

Maintenant je dois filtrer les éléments supprimés de la collection, mais ne peut pas utiliser autre chose que JPA. Aucune annotation spécifique d'hibernation autorisée. J'ai donc écrit une fonction post-charge:

@PostLoad 
public void postLoad() { 
    ArrayList<BillingItem>tempItems = new ArrayList<BillingItem>(); 

    Iterator<BillingItem> i = this.billingItems.iterator(); 
    BillingItem item; 
    while(i.hasNext()) { 
     item = i.next();    
     if(item.getStatus().equals("D")) { 
      tempItems.add(item);     
     }      
    } 

    this.billingItems.removeAll(tempItems); 
} 

Cependant quand il y a des éléments supprimés pour filtrer je vois

Mise en veille prolongée: mise à jour billing_on_item définie = null ch1_id où ch1_id =? et id =?

qui produit une exception car ch1_id est une clé étrangère et ne peut pas être nulle. Cependant, hibernate lie les paramètres pour corriger les valeurs. Pourquoi cette mise à jour se produit-elle en premier lieu? Comment puis-je corriger l'erreur?

Merci à l'avance,

Randy

Répondre

4

En retirant les éléments de la collection, vous dire Hibernate que l'association entre les deux entités n'existe plus, donc évidemment, Hibernate supprime ce qui se matérialise cette association dans la base de données: elle définit la clé étrangère sur null.

Ce que vous voulez sans doute est juste un getter dans votre entité qui retourne uniquement les éléments non supprimés:

public List<BillingItem> getNonDeletedItems() { 
    List<BillingItem> result = new ArrayList<BillingItem>(); 
    for (BillingItem item : this.billingItems) { 
     if (!"D".equals(item.getStatus()) { 
      result.add(item); 
     } 
    } 
    return result; 
} 
+0

Merci l'homme! Je n'ai même jamais pensé à une solution élégante et simple comme celle-ci. Logique. – randy

0

La ligne @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) dit qu'il en cascade toutes les mises à jour. Regardez dans CascadeType.

Questions connexes