[jira] Created: (OPENJPA-692) Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation

7 Messages Forum Options Options
Embed this topic
Permalink
JIRA jira@apache.org
[jira] Created: (OPENJPA-692) Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
Reply Threaded More
Print post
Permalink
Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
----------------------------------------------------------------------------------------

                 Key: OPENJPA-692
                 URL: https://issues.apache.org/jira/browse/OPENJPA-692
             Project: OpenJPA
          Issue Type: Bug
            Reporter: Pinaki Poddar
            Assignee: Pinaki Poddar
             Fix For: 1.3.0


Originally reported in user group message [1] by Frank Schwarz

If
a) Entities A and B that are related in a one-to-many and many-to-one bi-directional relation (typical Parent-Child pattern)
b) mapped using a JoinTable instead of conventional mappedBy

then
update/delete operation fails with OptimisticException (which itself is a catch-all and sometimes misleading).


Typical mapping that encounters this error:

public class Person {
        @Id
        private long ssn;
       
        @OneToMany(cascade=CascadeType.ALL)
        @JoinTable(name="J_PERSON_ADDRESSES",
                        joinColumns               = @JoinColumn(name="PERSON_SSN",    referencedColumnName="SSN"),
                        inverseJoinColumns = @JoinColumn(name="ADDRESS_PHONE", referencedColumnName="PHONE"))
    private Set<Address> addresses = new HashSet<Address>();

public class Address {
   @Id
   private String phone;
       
    @ManyToOne
    @JoinColumn(table="J_PERSON_ADDRESSES", referencedColumnName="SSN")
    private Person person;

[1] http://n2.nabble.com/bidirectional-one-to-many-relationship-with-join-table-tc678479.html


--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

JIRA jira@apache.org
[jira] Commented: (OPENJPA-692) Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
Reply Threaded More
Print post
Permalink

    [ https://issues.apache.org/jira/browse/OPENJPA-692?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12621217#action_12621217 ]

Frank Schwarz commented on OPENJPA-692:
---------------------------------------

I did some additional testing with Hibernate3. It seems that Hibernate is very robust on this topic.

The following mappings worked as expected:
1.
@Entity
public class Person {

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private long id;

        @OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
        @JoinTable(name="PERSON_ADDRESS",
                  joinColumns=@JoinColumn(name="PERSON_ID", referencedColumnName="ID"),
                  inverseJoinColumns=@JoinColumn(name="ADDRESS_ID", referencedColumnName="ID"))
        private Set<Address> addresses = new HashSet<Address>();
}

@Entity
@SecondaryTable(name="PERSON_ADDRESS", pkJoinColumns=@PrimaryKeyJoinColumn(name="ADDRESS_ID"))
public class Address {

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private long id;

        @ManyToOne
        @JoinColumn(table="PERSON_ADDRESS", referencedColumnName="ID")
        private Person person;
}
------%<----------------

2.
@Entity
public class Person {

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private long id;

        @OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
        private Set<Address> addresses = new HashSet<Address>();
}

@Entity
@SecondaryTable(name="PERSON_ADDRESS", pkJoinColumns=@PrimaryKeyJoinColumn(name="ADDRESS_ID"))
public class Address {

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private long id;

        @ManyToOne
        @JoinColumn(table="PERSON_ADDRESS")
        private Person person;
}
------%<----------------

3.
@Entity
public class Person {

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private long id;

        @OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
        private Set<Address> addresses = new HashSet<Address>();
}

@Entity
public class Address {

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private long id;

        @ManyToOne
        @JoinTable(name="PERSON_ADDRESS", joinColumns=@JoinColumn(name="ADDRESS_ID"))
        private Person person;
}


Not working with Hibernate is leaving out the "mappedBy" attribute of the Person.addresses field annotation in the first mapping example.

Personally, I would like to see the third example mapping working. It uses minimal annotations but remains semantically understandable. And it conforms with the spirit of JSR220 disapproving additional annotations on a "mapped-by" field.

> Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
> ----------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-692
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-692
>             Project: OpenJPA
>          Issue Type: Bug
>            Reporter: Pinaki Poddar
>            Assignee: Pinaki Poddar
>             Fix For: 1.3.0
>
>
> Originally reported in user group message [1] by Frank Schwarz
> If
> a) Entities A and B that are related in a one-to-many and many-to-one bi-directional relation (typical Parent-Child pattern)
> b) mapped using a JoinTable instead of conventional mappedBy
> then
> update/delete operation fails with OptimisticException (which itself is a catch-all and sometimes misleading).
> Typical mapping that encounters this error:
> public class Person {
> @Id
> private long ssn;
>
> @OneToMany(cascade=CascadeType.ALL)
> @JoinTable(name="J_PERSON_ADDRESSES",
> joinColumns               = @JoinColumn(name="PERSON_SSN",    referencedColumnName="SSN"),
> inverseJoinColumns = @JoinColumn(name="ADDRESS_PHONE", referencedColumnName="PHONE"))
>     private Set<Address> addresses = new HashSet<Address>();
> public class Address {
>    @Id
>    private String phone;
>
>     @ManyToOne
>     @JoinColumn(table="J_PERSON_ADDRESSES", referencedColumnName="SSN")
>     private Person person;
> [1] http://n2.nabble.com/bidirectional-one-to-many-relationship-with-join-table-tc678479.html

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

JIRA jira@apache.org
[jira] Commented: (OPENJPA-692) Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
Reply Threaded More
Print post
Permalink
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/OPENJPA-692?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12621361#action_12621361 ]

Pinaki Poddar commented on OPENJPA-692:
---------------------------------------

With SVN Commit 68442, OpenJPA addresses the bi-directional mapping with a JoinTable when mapping is annotated is two independent mappings at both ends of the relationship i.e. no 'mappedBy' attribute links the two ends.
Can you try that mapping with these latest changes to let us know whether that works for you? I have tested them and the check-in test cases are available with revision 68443.

The other variants you have mentioned with @SecondaryTable annotations need to be tested with OpenJPA.

> Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
> ----------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-692
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-692
>             Project: OpenJPA
>          Issue Type: Bug
>            Reporter: Pinaki Poddar
>            Assignee: Pinaki Poddar
>             Fix For: 1.3.0
>
>
> Originally reported in user group message [1] by Frank Schwarz
> If
> a) Entities A and B that are related in a one-to-many and many-to-one bi-directional relation (typical Parent-Child pattern)
> b) mapped using a JoinTable instead of conventional mappedBy
> then
> update/delete operation fails with OptimisticException (which itself is a catch-all and sometimes misleading).
> Typical mapping that encounters this error:
> public class Person {
> @Id
> private long ssn;
>
> @OneToMany(cascade=CascadeType.ALL)
> @JoinTable(name="J_PERSON_ADDRESSES",
> joinColumns               = @JoinColumn(name="PERSON_SSN",    referencedColumnName="SSN"),
> inverseJoinColumns = @JoinColumn(name="ADDRESS_PHONE", referencedColumnName="PHONE"))
>     private Set<Address> addresses = new HashSet<Address>();
> public class Address {
>    @Id
>    private String phone;
>
>     @ManyToOne
>     @JoinColumn(table="J_PERSON_ADDRESSES", referencedColumnName="SSN")
>     private Person person;
> [1] http://n2.nabble.com/bidirectional-one-to-many-relationship-with-join-table-tc678479.html

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

JIRA jira@apache.org
[jira] Commented: (OPENJPA-692) Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
Reply Threaded More
Print post
Permalink
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/OPENJPA-692?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12621390#action_12621390 ]

Frank Schwarz commented on OPENJPA-692:
---------------------------------------

I tried the mapping as specified in the description field of this case.

It works with current trunk (revision 684688/1.3.0-SNAPSHOT). Schema, SQL statements and runtime behavior are OK with one exception:

Dissolving relationship, e.g.:
                        Address address = person.getAddresses().iterator().next();
                        person.getAddresses().remove(address);
                        address.setPerson(null);

leads to UPDATE PERSON_ADDRESS SET PERSON_SSN = ? WHERE ADDRESS_PHONE = ? [params=(null) null, (long) 3]
Actually it has to be DELETE FROM PERSON_ADDRESS WHERE ADDRESS_PHONE = ? [params=(long) 3]. Otherwise the join-table will get filled with meaningless <NULL, ADDRESS_PHONE> tupels


> Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
> ----------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-692
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-692
>             Project: OpenJPA
>          Issue Type: Bug
>            Reporter: Pinaki Poddar
>            Assignee: Pinaki Poddar
>             Fix For: 1.3.0
>
>
> Originally reported in user group message [1] by Frank Schwarz
> If
> a) Entities A and B that are related in a one-to-many and many-to-one bi-directional relation (typical Parent-Child pattern)
> b) mapped using a JoinTable instead of conventional mappedBy
> then
> update/delete operation fails with OptimisticException (which itself is a catch-all and sometimes misleading).
> Typical mapping that encounters this error:
> public class Person {
> @Id
> private long ssn;
>
> @OneToMany(cascade=CascadeType.ALL)
> @JoinTable(name="J_PERSON_ADDRESSES",
> joinColumns               = @JoinColumn(name="PERSON_SSN",    referencedColumnName="SSN"),
> inverseJoinColumns = @JoinColumn(name="ADDRESS_PHONE", referencedColumnName="PHONE"))
>     private Set<Address> addresses = new HashSet<Address>();
> public class Address {
>    @Id
>    private String phone;
>
>     @ManyToOne
>     @JoinColumn(table="J_PERSON_ADDRESSES", referencedColumnName="SSN")
>     private Person person;
> [1] http://n2.nabble.com/bidirectional-one-to-many-relationship-with-join-table-tc678479.html

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Pinaki Poddar
Re: [jira] Commented: (OPENJPA-692) Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
Reply Threaded More
Print post
Permalink
Hi,
                        Address address = person.getAddresses().iterator().next();
                        person.getAddresses().remove(address);
                        address.setPerson(null);

Generally speaking, in JPA world, nulling a relation or removing an element from a collection do not imply that the corresponding database record is deleted.
To delete records from database, em.remove() needs to be invoked.

However, delete-orphan behavior that your example code implies is supported by OpenJPA with @Dependent/@ElementDependent annotation on a relation.  


JIRA jira@apache.org wrote:
    [ https://issues.apache.org/jira/browse/OPENJPA-692?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12621390#action_12621390 ]

Frank Schwarz commented on OPENJPA-692:
---------------------------------------

I tried the mapping as specified in the description field of this case.

It works with current trunk (revision 684688/1.3.0-SNAPSHOT). Schema, SQL statements and runtime behavior are OK with one exception:

Dissolving relationship, e.g.:
                        Address address = person.getAddresses().iterator().next();
                        person.getAddresses().remove(address);
                        address.setPerson(null);

leads to UPDATE PERSON_ADDRESS SET PERSON_SSN = ? WHERE ADDRESS_PHONE = ? [params=(null) null, (long) 3]
Actually it has to be DELETE FROM PERSON_ADDRESS WHERE ADDRESS_PHONE = ? [params=(long) 3]. Otherwise the join-table will get filled with meaningless <NULL, ADDRESS_PHONE> tupels


> Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
> ----------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-692
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-692
>             Project: OpenJPA
>          Issue Type: Bug
>            Reporter: Pinaki Poddar
>            Assignee: Pinaki Poddar
>             Fix For: 1.3.0
>
>
> Originally reported in user group message [1] by Frank Schwarz
> If
> a) Entities A and B that are related in a one-to-many and many-to-one bi-directional relation (typical Parent-Child pattern)
> b) mapped using a JoinTable instead of conventional mappedBy
> then
> update/delete operation fails with OptimisticException (which itself is a catch-all and sometimes misleading).
> Typical mapping that encounters this error:
> public class Person {
> @Id
> private long ssn;
>
> @OneToMany(cascade=CascadeType.ALL)
> @JoinTable(name="J_PERSON_ADDRESSES",
> joinColumns               = @JoinColumn(name="PERSON_SSN",    referencedColumnName="SSN"),
> inverseJoinColumns = @JoinColumn(name="ADDRESS_PHONE", referencedColumnName="PHONE"))
>     private Set<Address> addresses = new HashSet<Address>();
> public class Address {
>    @Id
>    private String phone;
>
>     @ManyToOne
>     @JoinColumn(table="J_PERSON_ADDRESSES", referencedColumnName="SSN")
>     private Person person;
> [1] http://n2.nabble.com/bidirectional-one-to-many-relationship-with-join-table-tc678479.html

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
JIRA jira@apache.org
[jira] Commented: (OPENJPA-692) Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
Reply Threaded More
Print post
Permalink
In reply to this post by JIRA jira@apache.org

    [ https://issues.apache.org/jira/browse/OPENJPA-692?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12621712#action_12621712 ]

Frank Schwarz commented on OPENJPA-692:
---------------------------------------

With latest changes in trunk the dissolution of associations seems to work, i.e. an SQL delete statement is now used instead of an SQL update-set-null statement.

> Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
> ----------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-692
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-692
>             Project: OpenJPA
>          Issue Type: Bug
>            Reporter: Pinaki Poddar
>            Assignee: Pinaki Poddar
>             Fix For: 1.3.0
>
>
> Originally reported in user group message [1] by Frank Schwarz
> If
> a) Entities A and B that are related in a one-to-many and many-to-one bi-directional relation (typical Parent-Child pattern)
> b) mapped using a JoinTable instead of conventional mappedBy
> then
> update/delete operation fails with OptimisticException (which itself is a catch-all and sometimes misleading).
> Typical mapping that encounters this error:
> public class Person {
> @Id
> private long ssn;
>
> @OneToMany(cascade=CascadeType.ALL)
> @JoinTable(name="J_PERSON_ADDRESSES",
> joinColumns               = @JoinColumn(name="PERSON_SSN",    referencedColumnName="SSN"),
> inverseJoinColumns = @JoinColumn(name="ADDRESS_PHONE", referencedColumnName="PHONE"))
>     private Set<Address> addresses = new HashSet<Address>();
> public class Address {
>    @Id
>    private String phone;
>
>     @ManyToOne
>     @JoinColumn(table="J_PERSON_ADDRESSES", referencedColumnName="SSN")
>     private Person person;
> [1] http://n2.nabble.com/bidirectional-one-to-many-relationship-with-join-table-tc678479.html

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

JIRA jira@apache.org
[jira] Resolved: (OPENJPA-692) Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
Reply Threaded More
Print post
Permalink
In reply to this post by JIRA jira@apache.org

     [ https://issues.apache.org/jira/browse/OPENJPA-692?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Pinaki Poddar resolved OPENJPA-692.
-----------------------------------

    Resolution: Fixed

> Bi-directional One-to-Many mapping with a JoinTable fails for Update or Delete operation
> ----------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-692
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-692
>             Project: OpenJPA
>          Issue Type: Bug
>            Reporter: Pinaki Poddar
>            Assignee: Pinaki Poddar
>             Fix For: 1.3.0
>
>
> Originally reported in user group message [1] by Frank Schwarz
> If
> a) Entities A and B that are related in a one-to-many and many-to-one bi-directional relation (typical Parent-Child pattern)
> b) mapped using a JoinTable instead of conventional mappedBy
> then
> update/delete operation fails with OptimisticException (which itself is a catch-all and sometimes misleading).
> Typical mapping that encounters this error:
> public class Person {
> @Id
> private long ssn;
>
> @OneToMany(cascade=CascadeType.ALL)
> @JoinTable(name="J_PERSON_ADDRESSES",
> joinColumns               = @JoinColumn(name="PERSON_SSN",    referencedColumnName="SSN"),
> inverseJoinColumns = @JoinColumn(name="ADDRESS_PHONE", referencedColumnName="PHONE"))
>     private Set<Address> addresses = new HashSet<Address>();
> public class Address {
>    @Id
>    private String phone;
>
>     @ManyToOne
>     @JoinColumn(table="J_PERSON_ADDRESSES", referencedColumnName="SSN")
>     private Person person;
> [1] http://n2.nabble.com/bidirectional-one-to-many-relationship-with-join-table-tc678479.html

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.