@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;
...
}
_orfani rimangono nel database anche con orphanRemoval = true su uno-a-molti (JPA/Hibernate)
@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;
...
}
Quando questo Set viene aggiornato i activePolicyRules esistenti hanno la loro category_policy_id impostato su null in il database e quelli nuovi sono inseriti. Mi piacerebbe che gli originali venissero cancellati.
Ho pensato di aggiungere orphanRemoval = true, ma non lo è. Altre domande che ho visto su questo sembrano avere relazioni bidirezionali e l'impostazione del genitore su null lo risolve, ma questa non è una relazione bidirezionale.
Qualche suggerimento?
usando Hibernate 3.5.3
Edit: Questo accade solo quando esiste un AbstractPolicyRule esistente nel database, rimuovo dalla lista e quindi salvare di nuovo Categoria. La sua chiave esterna, category_policy_id, è impostata su null invece di essere cancellata.
[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
provato anche un tavolo da unirsi in quanto la documentazione Hibernate scoraggia il modo precedente:
@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;
...
}
Questo ha lo stesso problema. La riga nella tabella di mapping viene eliminata, ma AbstractPolicyRule contiene ancora l'elemento rimosso.
Lo scenario che ho provato era in realtà molto vicino alla tua modifica. Ho modificato il mio test per rimuovere l'elemento esistente dalla raccolta senza aggiungerne un altro e viene comunque eliminato. Nota che non sto usando alcuna eredità (penso che tu possa essere). –