0

最近、Eclipse リンクのバージョン アップグレードを 2.1 から 2.5 にアップグレードしました。私のエンティティクラスは次のようになります

    /**
     * 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;

問題のあるコード スニペットを以下に示します。アップグレード前は問題なく動作していましたが、現在は assertEquals で失敗しています。ここで、managerID は部下が 0 人の従業員を参照しています。

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());

EclipseLink 2.1では、次のクエリが起動されることがわかりました

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))

ただし、アップグレード後、次のクエリが実行されます

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 = ?)

上記のクエリを手動で実行すると。以下が結果です。(Oracle と Postgresql の両方で)

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

これにより、subs.size() が予想される 0 ではなく 1 を返します。subs.get(0) は null を返します。

質問 1: subs.size() が再び 0 を返すようにするには、何を変更する必要がありますか。 質問 2: いくつかの問題があり、アップグレード後に表面化しました。アップグレード関連の問題について参照できるドキュメントはありますか?

4

1 に答える 1

1

SELECT 句で関連オブジェクトを選択するためのドット表記の使用法が、内部結合の代わりに外部結合を使用するように変更されたようです。これは奇妙に思えますが、意図的であるか、仕様に基づいている可能性があります。バグをログに記録して、元に戻すことができます。

結合を制御するには、FROM 句で正しく定義するだけです (通常、正しい使用法を確保するために、常に FROM 句で結合を定義するのが最善です)。

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

また、null が返されるというバグをログに記録します。これは、OneToOne を選択する場合には意味がありますが、OneToMany ではなく、空にする必要があります。

JPA 仕様では、OneToMany のドット概念の使用が許可されていないことに注意してください。結合構文を使用する必要があります。TopLinkではこれが可能ですが、結合構文を使用する方がよいため、結合と結合タイプを認識できます。

于 2013-07-02T14:19:36.703 に答える