java - Hibernate triggering constraint violations using orphanRemoval -


I'm having trouble with the setup of JPA / Hibernate (3.5.3), where I have a unit, a " Account "category, which has a list of child organizations," contact "example I am trying to be able to add / remove instances of contact in a list & lt; Contact & gt; Account property

By adding a new instance to the Setting and Calling Order Update (account), everything remains pretty fine, if I then choose to delete the contact from the list and then call the Save and Update, then SQL Hibernate To set up the account_id column to set up to clear, which violates database barrier.

What am I doing? / P>

The code below is clearly a simplified summary, but I think it involves the problem because I see the same code in different codes, which in fact is about this simple is.

SQL:

  Create account table (INT account_id); Create table contact (INT contact_id, INT account_id reference account (account_id));  

Java:

  @Antie class account {@Id @Column public long id; @OneToMany (cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn (name = "account_id") public list & lt; Contacts & gt; Contacts; } @ Entity Class Contact {@Id @Column Public Long id; @ManyToOne (optional = false) @ join column (name = "account_id", tapable = incorrect) account of public account; } Account Account = New Account (); Contact Contact = New Contact (); Account.contacts.add (contact); SaveOrUpdate (account); // After some time, another servlet request .... such as account.contacts.remove (contact); SaveOrUpdate (account);  

Result:

Contact Contact SET account_id = null WHERE contact_id =? # 1:

Edit It may be that this is actually a bug

Edit # 2:

I think to work There is a solution, but the Hibernate API class account {@SuppressWarnings ("deprecation") @OneToMany (cascade = CascadeType.ALL, mapped = "account") @cascade (org.hibernate .annotations.CascadeType.DELETE_ORPHAN) @JoinColumn (name = "account_id", drain = false) Private set & lt; Contacts & gt; Contact = New Hashet & lt; Contacts & gt; (); } Class contacts {@ManyToOne (optional = false) @Joint column (name = "account_id", faucet = incorrect) Personal account account; }

Since cascade type in hibernation DELETE_ORPHAN is deprecated, I believe it has been transferred from the JPA version 2, but there is a lack of implementation.

Some comments:

  • Since you have bi-directional collaboration Do not forget that code> mapped attribute
  • to declare you a party owned by the association, while working with bi-directional organizations, And I suggest using defensive methods for it (shown below).
  • and you equal and hashode at contact <001>

Apply, therefore, account , modify mapping in this way:

  @intexty public class account {@Id @GeneratedValue public long id; @OneToMany (cascade = CascadeType.ALL, mapped = "account", orphanRemoval = true) public list & lt; Contacts & gt; Contact = New ArrayList & lt; Contacts & gt; (); Public Zero addToContacts (Contact Contact) {this.contacts.add (contact); Contact.setAccount (this); } Public Zero Deletion Contact Contact (Contact Contact) {this.contacts.remove (contact); Contact.setAccount (zero); } // getters, setters}  

in contact , the important part is that the @ManyToOne field should be optional flag is set to false :

  @interity public class contacts {@Id @ generatedValue public long id; @ManyToOne (optional = false) account of public account; // getters, setters, equals, hashcode}  

With these modifications, the following functions:

  account account = new account (); Contact Contact = New Contact (); Account.addToContact (contact); Em.persist (account); Em.flush (); AssertNotNull (account.getId ()); Get assertNotNull (account.getContacts () (0) .getId ().); AssertEquals (1, account.getContacts (). Size ()); Account.removeFromContact (contact); Em.merge (account); Em.flush (); AssertEquals (0, account.getContacts (). Size ());  

and orphan contact is removed, as tested with Hibernate 3.5.3-Final.


Comments