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
andhashode
atcontact
<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
Post a Comment