openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Fay Wang (JIRA)" <j...@apache.org>
Subject [jira] Updated: (OPENJPA-292) Extra JOIN on eager bi-directional relationship
Date Wed, 23 Jul 2008 02:03:33 GMT

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

Fay Wang updated OPENJPA-292:
-----------------------------

    Attachment: openjpa_292.patch

The problem described by Rob is similar to JIRA-241 and JIRA-134 scenario 3 in that they are
all about the retrieval of the inverse relationship. This JIRA deals with 1-1 relationship
while JIRA-241 is for 1-many relationship. The following test case is used to reproduce the
problem:

@Entity
public class EntityC  {
    @GeneratedValue(strategy=GenerationType.IDENTITY)
	@Id private int id;
    
    private String name;
    private int age;
    private int balance;
    
	@OneToOne(fetch=FetchType.EAGER, mappedBy="entityC")
	private EntityD entityD = null;
...
}

@Entity
public class EntityD  {
    @GeneratedValue(strategy=GenerationType.IDENTITY)
	@Id private int id;
    
    private String name;
    private int loginCount;
    private int logoutCount;
    private String email;
    
	@OneToOne(fetch=FetchType.EAGER)
	private EntityC entityC = null;
...
}

The test case:
        EntityManagerImpl em = (EntityManagerImpl) emf.createEntityManager();
        String query = "select c FROM EntityC c";
        Query q = em.createQuery(query);
        List list = q.getResultList();
        System.out.println("size = " + list.size());
        for (int i = 0; i < list.size(); i++) {
            EntityC c = (EntityC)list.get(i);
            System.out.println("EntityC = " + c.getName());
            System.out.println("EntityD = " + c.getD().getName());
            System.out.println("EntityD's C = " + c.getD().getC().getName());
            System.out.println();
        }

The following SQL are generated:

(1) SELECT t0.id, t0.age, t0.balance, t1.id, t1.email, t1.loginCount, t1.logoutCount, t1.name,
t0.name 
    FROM EntityC t0 
    LEFT OUTER JOIN EntityD t1 ON t0.id = t1.ENTITYC_ID 

(2) SELECT t1.id, t1.age, t1.balance, t2.id, t2.email, t2.loginCount, t2.logoutCount, t2.name,
t1.name 
    FROM EntityD t0 
    INNER JOIN EntityC t1 ON t0.ENTITYC_ID = t1.id 
    LEFT OUTER JOIN EntityD t2 ON t1.id = t2.ENTITYC_ID WHERE t0.id = ?  optimize for 1 row
[params=(int) 101]


(3) SELECT t1.id, t1.age, t1.balance, t2.id, t2.email, t2.loginCount, t2.logoutCount, t2.name,
t1.name 
    FROM EntityD t0 
    INNER JOIN EntityC t1 ON t0.ENTITYC_ID = t1.id 
    LEFT OUTER JOIN EntityD t2 ON t1.id = t2.ENTITYC_ID WHERE t0.id = ?  optimize for 1 row
[params=(int) 102]

(4) SELECT t1.id, t1.age, t1.balance, t2.id, t2.email, t2.loginCount, t2.logoutCount, t2.name,
t1.name 
    FROM EntityD t0 
    INNER JOIN EntityC t1 ON t0.ENTITYC_ID = t1.id 
    LEFT OUTER JOIN EntityD t2 ON t1.id = t2.ENTITYC_ID WHERE t0.id = ?  optimize for 1 row
[params=(int) 104]

(5) SELECT t1.id, t1.age, t1.balance, t2.id, t2.email, t2.loginCount, t2.logoutCount, t2.name,
t1.name 
    FROM EntityD t0 
    INNER JOIN EntityC t1 ON t0.ENTITYC_ID = t1.id 
    LEFT OUTER JOIN EntityD t2 ON t1.id = t2.ENTITYC_ID WHERE t0.id = ?  optimize for 1 row
[params=(int) 103]

Since there are four entityD in the database, openjpa makes four separate SQL calls to retrieve
each entityD (sql (2) - (5)). These sql has inner join and left outer join between EntityC
and EntityD as they are bi-directional 1-1 relationship.

The attached patch detects this inverse relationship (mappedBy relationship) to get rid of
sql (2) -(5).






> 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
>         Attachments: openjpa_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 is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message