Orphans bleiben in der Datenbank, auch wenn orphanRemoval = true für eine Eins-zu-Viele-Beziehung ist (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;

  ...
}

Wenn dieses Set aktualisiert wird, wird für die vorhandenen activePolicyRules die category_policy_id in der Datenbank auf null gesetzt, und neue werden eingefügt. Ich möchte, dass die Originalen gelöscht werden.

Ich dachte, das Hinzufügen von orphanRemoval = true würde das tun, aber es ist nicht so. Andere Fragen, die ich dazu gesehen habe, scheinen bidirektionale Beziehungen zu haben, und das Setzen des übergeordneten Elements auf Null löst es, aber dies ist keine bidirektionale Beziehung.

Irgendwelche Vorschläge

Verwenden von Hibernate 3.5.3

Bearbeiten: Dies geschieht nur, wenn eine vorhandene AbstractPolicyRule in der Datenbank vorhanden ist. Ich entferne sie aus der Liste und speichere die Kategorie erneut. Der Fremdschlüssel category_policy_id wird nicht gelöscht, sondern auf null gesetzt.

[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

Auch eine Join-Tabelle ausprobiert, da die Dokumentation zum Ruhezustand von der vorherigen Vorgehensweise abrät:

@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;

  ...
}

Dies hat das gleiche Problem. Die Zeile in der Zuordnungstabelle wird gelöscht, die AbstractPolicyRule enthält jedoch weiterhin das entfernte Element.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage