Search code examples
javaoraclejpapersistenceeclipselink

Eclipse link version upgrade from 2.1 to 2.5 causing issue


Recently, I upgraded Eclipse link version upgrade from 2.1 to 2.5. My entity class looks like following

    /**
     * For subordinates, the manager employee.
     */
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="MANAGER", insertable=false, updatable=false, nullable=true)
private Employee manager;

/**
 * For employees with subordinates, the subordinate employee. 
 */
@OneToMany(mappedBy="manager", fetch=FetchType.LAZY)
    @OrderBy("subordinate_order asc")
private List<Employee> sub;

Please find below the code snippet having issue. It was working fine, before upgrade, but now it is failing at assertEquals. Here, managerID is referring to an employee which is having 0 subordinates.

Query query = getEntityManager().createQuery(
            "select e.sub from Employee e where e.id = :id");
    query.setParameter("id", managerId);

    List<Employee> subs = query.getResultList();
    assertEquals("Wrong number of subs for manager emp id "+managerId,
            0, subs.size());

I have found that with EclipseLink 2.1 following query used to get fired

SELECT e0.ID, e0.PROP1, e0.PROP2, e0.SUBORDINATE_ORDER, e0.MANAGER FROM EMPLOYEE e0, EMPLOYEE e1 WHERE ((e1.ID = ?) AND (e0.MANAGER = e1.ID))

But after upgrade following query is being fired

SELECT e0.ID, e0.PROP1, e0.PROP2, e0.SUBORDINATE_ORDER, e0.MANAGER FROM EMPLOYEE e1 LEFT OUTER JOIN EMPLOYEE e0 ON (e0.MANAGER = e1.ID) WHERE (e1.ID = ?)

When I execute the above query manually. following is the result. (On both Oracle and Postgresql)

id      prop1        prop2     subordinate_order     manager   
------  ----------  --------   ----------            -------------- 
 (null)  (null)      (null)          (null)      (null) 

This is causing subs.size() to return 1 instead of expected 0. subs.get(0) returns null.

Question 1: What needs to be modified so that subs.size() again start returning 0. Question 2: I am having couple of problems, which have surfaced after the upgrade. Do we have some document, which can be referred for upgrade related issues?


Solution

  • It looks like the usage of the dot notation to select a related object in the SELECT clause was changed to use an outer join instead of an inner join. This seems odd, but may have been intentional, or spec dictated. You could try logging a bug to have it switched back.

    To control the join, just define it correctly in the FROM clause (in general it is best to always define your joins in the FROM clause to ensure correct usage).

    select s from Employee e join e.sub s where e.id = :id
    

    Also log a bug that null is returned, this may make sense for selecting a OneToOne, but not a OneToMany, it should be empty.

    Note that the JPA spec does not allow usage of the dot notion for OneToMany, you are required to use the join syntax. EclipseLink allows this, but it is better to use the join syntax, so you are aware of the join and the join type.