Les orphelins restent dans la base de données même avec orphelinsRemoval = true sur une relation un-à-plusieurs (JPA / Hibernate)
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "company_policies")
@DiscriminatorColumn(name = "rule_name")
public abstract class AbstractPolicyRule implements Serializable {
@Transient
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
private String value;
...
}
_
@Entity
public class Category implements Serializable {
@Transient
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(name = "category_name")
private String name;
@OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval = true)
@JoinColumn(name = "category_policy_id", referencedColumnName = "id")
private Set<AbstractPolicyRule> activePolicyRules;
...
}
Lorsque cet Ensemble est mis à jour de l'existant activePolicyRules ont leur category_policy_id la valeur null dans la base de données et de nouveaux sont insérés. J'aimerais que celles à l'origine à être supprimé.
J'ai pensé à l'ajout de la orphanRemoval = true serait de le faire mais il ne l'est pas. D'autres questions que j'ai vu sur ce semblent avoir bi-directionnelle des relations et le réglage de la mère à null elle n'en résout, mais ce n'est pas un bi-directionnelle de la relation.
Des suggestions?
De L'Utilisation D'Hibernate 3.5.3
Edit:
Cela se produit uniquement lorsqu'un AbstractPolicyRule existe dans la base de données, je le supprime de la liste et ensuite enregistrer la Catégorie de nouveau. C'est de clé étrangère, category_policy_id, est mis à null au lieu d'être supprimées.
[DEBUG] Collection found: [domain.category.Category.activePolicyRules#1], was:
[<unreferenced>] (initialized)
[DEBUG] Flushed: 0 insertions, 2 updates, 0 deletions to 2 objects
[DEBUG] Flushed: 1 (re)creations, 0 updates, 1 removals to 1 collections
...
[DEBUG] Deleting collection: [domain.category.Category2.activePolicyRules#1]
[DEBUG] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
[DEBUG] update company_policies set category_policy_id=null where category_policy_id=?
[DEBUG] done deleting collection
Aussi essayé une table de jointure depuis la documentation Hibernate décourage la manière précédente:
@Entity
public class Category implements Serializable {
@Transient
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(name = "category_name")
private String name;
@OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval = true)
@JoinTable(name = "policy_rule_mapping",
joinColumns = @JoinColumn(name = "category_id"),
inverseJoinColumns = @JoinColumn(name = "rule_id"))
private Set<AbstractPolicyRule> activePolicyRules;
...
}
Cela a le même problème. La ligne dans la table de correspondance est supprimé, mais la AbstractPolicyRule contient toujours l'élément supprimé.
source d'informationauteur Josh
Vous devez vous connecter pour publier un commentaire.
Je suis en utilisant
orphanRemoval=true
avec une unidirectionnel Un-à-Plusieurs association sans problème.Et effectivement, j'ai testé votre code et le scénario suivant (
AbstractPolicyRule
la mise en œuvre deequals
/hashCode
correctement):fonctionne comme prévu. Ci-dessous les traces générées:
La première règle de politique est supprimé.
Si ce n'est pas représentatif de ce que vous faites, vous devriez peut-être fournir plus de code.
Mise à jour: Répondant à un commentaire de l'OP...
Juste une supposition: depuis
orphanRemoval
est une JPA chose, je me demande sisaveOrUpdate
permettra de traiter de façon appropriée (en fait, je pensais que vous étiez à l'aide de laEntityManager
API puisque vous avez mentionné JPA).Assurez-vous d'abord de vos classes implémentent l'
hashCode()
etequals()
de méthodes, de sorte que hibernate sait que ce sont précisément ces éléments sont supprimés de l'ensemble.Puis essayez de définir les hibernate
@Cascade
annotation, en précisant le delete-orphan cascade de même type et de l'observateur de savoir si la même chose arrive. Si elle fonctionne de la façon dont vous le souhaitez signaler un bug en mode veille prolongée et utiliser temporairement la propriété d'annotation. Autrement - mise à jour de la question avec les détails