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

Richard Zowalla commented on OPENJPA-292:
-----------------------------------------

Still reproducible on current master (4.2.0-SNAPSHOT, 4bad79e2f) with Derby. 
Reproducer, e.g. in 
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/repro:

{code:java|title=Acct292.java}
package org.apache.openjpa.persistence.repro;

import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;

@Entity
public class Acct292 {
    @Id
    private int id;

    @OneToOne(fetch = FetchType.EAGER)
    private Prof292 profile;

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public Prof292 getProfile() { return profile; }
    public void setProfile(Prof292 profile) { this.profile = profile; }
}
{code}
{code:java|title=Prof292.java}
package org.apache.openjpa.persistence.repro;

import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;

@Entity
public class Prof292 {
    @Id
    private String userid;

    @OneToOne(fetch = FetchType.EAGER, mappedBy = "profile")
    private Acct292 account;

    public String getUserid() { return userid; }
    public void setUserid(String userid) { this.userid = userid; }
    public Acct292 getAccount() { return account; }
    public void setAccount(Acct292 account) { this.account = account; }
}
{code}
{code:java|title=TestRepro292.java}
package org.apache.openjpa.persistence.repro;

import jakarta.persistence.EntityManager;

import org.apache.openjpa.persistence.test.SQLListenerTestCase;

/**
 * OPENJPA-292: loading the owner of an eager bidirectional one-to-one joins 
the owner table a second time.
 */
public class TestRepro292 extends SQLListenerTestCase {
    @Override
    public void setUp() {
        setUp(Acct292.class, Prof292.class, CLEAR_TABLES);
        try (EntityManager em = emf.createEntityManager()) {
            em.getTransaction().begin();
            Prof292 p = new Prof292();
            p.setUserid("u1");
            Acct292 a = new Acct292();
            a.setId(1);
            a.setProfile(p);
            p.setAccount(a);
            em.persist(p);
            em.persist(a);
            em.getTransaction().commit();
        }
    }

    public void testFindOwnerJoinsOwnerTableOnce() {
        try (EntityManager em = emf.createEntityManager()) {
            resetSQL();
            Acct292 a = em.find(Acct292.class, 1);
            assertSame(a, a.getProfile().getAccount());
            for (String s : sql) {
                // the owner row is already selected as t0; joining Acct292 
again from the profile is redundant
                assertFalse(s, s.contains("JOIN Acct292"));
            }
        }
    }
}
{code}

Result: find(Acct292.class, 1) runs
{noformat}
SELECT t1.userid, t2.id FROM Acct292 t0 INNER JOIN Prof292 t1 ON 
t0.PROFILE_USERID = t1.userid LEFT OUTER JOIN Acct292 t2 ON t1.userid = 
t2.PROFILE_USERID WHERE t0.id = ?
{noformat}
The join back to Acct292 (t2) is not needed, the owner is t0.

> Extra JOIN on eager bi-directional relationship
> -----------------------------------------------
>
>                 Key: OPENJPA-292
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-292
>             Project: OpenJPA
>          Issue Type: Bug
>    Affects Versions: 1.0.0
>            Reporter: Rob Wisniewski
>            Priority: Major
>         Attachments: openjpa_292.patch, openjpa_292_1.patch, 
> testcase_241_292.patch
>
>
> I have a pretty simple 1-1 bi-directional relationship.  If I set both sides 
> to eager and then do a select on one side, the following SQL is executed:
> SELECT t1.USERID, t2.ACCOUNTID, t2.BALANCE
> , t2.CREATIONDATE, t2.LASTLOGIN, t2.LOGINCOUNT, t2.LOGOUTCOUNT, 
> t2.OPENBALANCE,
> t1.ADDRESS, t1.CREDITCARD, t1.EMAIL, t1.FULLNAME, t1.PASSWD FROM ACCOUNTEJB 
> t0 I
> NNER JOIN ACCOUNTPROFILEEJB t1 ON t0.PROFILE_USERID = t1.USERID LEFT OUTER 
> JOIN
> ACCOUNTEJB t2 ON t1.USERID = t2.PROFILE_USERID WHERE t0.ACCOUNTID = ?  
> optimize
> for 1 row
> the relationship is account <-> accountprofile.   you can see we actually do 
> 2 joins.
> This is one in a family of problems which was supposed to have been solved in 
> https://issues.apache.org/jira/browse/OPENJPA-134
> There is also a related issue where an uneeded load is done, which I 
> documented a while ago in https://issues.apache.org/jira/browse/OPENJPA-241
> I think this is a general comment on the lack of sophistication of the 
> persistence engine to understand when data is logically going to be there 
> anyways, and not to add joins or trigger data loading.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to