2

次のエンティティ クラスがあります (PersistentObjectSupport クラスから継承された ID):

@Entity
public class AmbulanceDeactivation extends PersistentObjectSupport implements Serializable {
    private static final long serialVersionUID = 1L;

    @Temporal(TemporalType.DATE) @NotNull
    private Date beginDate;

    @Temporal(TemporalType.DATE)
    private Date endDate;

    @Size(max = 250)
    private String reason;

    @ManyToOne @NotNull
    private Ambulance ambulance;

    /* Get/set methods, etc. */
}

Criteria API を使用して次のクエリを実行すると:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<AmbulanceDeactivation> cq = cb.createQuery(AmbulanceDeactivation.class);
Root<AmbulanceDeactivation> root = cq.from(AmbulanceDeactivation.class);
EntityType<AmbulanceDeactivation> model = root.getModel();
cq.where(cb.isNull(root.get(model.getSingularAttribute("endDate", Date.class))));
return em.createQuery(cq).getResultList();

ログに次の SQL が出力されます。

FINE: SELECT ID, REASON, ENDDATE, UUID, BEGINDATE, VERSION, AMBULANCE_ID FROM AMBULANCEDEACTIVATION WHERE (ENDDATE IS NULL)

ただし、前のコードの where() 行を次のように変更すると:

cq.where(cb.isNull(root.get(model.getSingularAttribute("endDate", Date.class))),
    cb.equal(root.get(model.getSingularAttribute("ambulance", Ambulance.class)), ambulance));

次のSQLを取得します。

FINE: SELECT ID, REASON, ENDDATE, UUID, BEGINDATE, VERSION, AMBULANCE_ID FROM AMBULANCEDEACTIVATION WHERE (AMBULANCE_ID = ?)

つまり、isNull 基準は完全に無視されます。あたかも存在しないかのようです (where() メソッドに等しい基準のみを指定すると、同じ SQL が出力されます)。

何故ですか?それはバグですか、それとも何か不足していますか?

4

2 に答える 2

2

EclipseLink を使用してコードと条件クエリをテストし (EclipseLink を使用していますよね?)、動作を再現しました。このisNull部分は単に無視されます。

ただし、Hibernate Entity Manager 3.5.1 では、次のクエリが生成されます。

select ambulanced0_.id as id7_, ambulanced0_.ambulance_id as ambulance5_7_, ambulanced0_.beginDate as beginDate7_, ambulanced0_.endDate as endDate7_, ambulanced0_.reason as reason7_ 
from AmbulanceDeactivation ambulanced0_ 
where (ambulanced0_.endDate is null) and ambulanced0_.ambulance_id=?

これは期待される結果です。したがって、これは JPA 2.0 プロバイダーのバグであると推測できます。

于 2010-06-10T23:06:10.877 に答える
1

EclipseLink 2.0 が埋め込まれた Glassfish 3.0.1 を使用して、同じ奇妙な動作がありました。

Glassfish 3.1.2 に含まれる Eclipselink 2.3 ライブラリを使用して、組み込みの eclipselink ライブラリを慎重に変更しようとしました。それは問題を解決しました。したがって、等しい条件での isNull チェックは、criteriaBuilder を使用した eclipselink のバグであることは間違いありません。

問題を解消するために、GlassFish 環境をすぐにアップグレードします。

于 2013-02-08T19:26:00.990 に答える