0

永続化レイヤーがSpring Rooで生成されたJPAエンティティで構成され、永続化プロバイダーとしてHibernate、基礎となるDBとしてMySqlを使用するSpring Webアプリケーションを開発しています。

私のエンティティの中には、次のように Roo で生成されDetectionた tstampjava.util.Dateフィールドを持つクラスがあります。

entity jpa --class ~.data.Detection
...
field date --fieldName tstamp --type java.util.Date
...
finder add findDetectionsByTstampBetween

(もちろん、実行後にファインダーメソッドが選択されましたfinder list

私のコントローラーコードでは、私が呼び出す時点で:

List<Detection> detections = Detection.findDetectionsByTstampBetween(from, to).getResultList(); 

from と to は 2 つ有効ですjava.util.Date(s)。ただし、サンプル データをテストするとき (指定された from の選択に対して、返されるリストが空にならないようにした後)、空のリストを取得し、その理由を調査しました。

Tomcat ログで、Hibernate が次の SQL を生成していることがわかりました。

Hibernate: select detection0_.id as id1_3_, ...etc..., detection0_.tstamp as tstamp4_3_ from detection detection0_ where detection0_.tstamp>=?

where 句にはAND detection0_.tstamp<=?、他の日付範囲の制限を確認して、末尾に " " が含まれている必要があります。Detection.findDetectionsByTstampBetween(Date minTstamp, Date maxTstamp)で生成されたメソッドを調べたところ、Detection_Roo_Finder.aj実際には createQuery の呼び出しに「AND」が含まれています。

public static TypedQuery<Detection> Detection.findDetectionsByTstampBetween(Date minTstamp, Date maxTstamp) {
        if (minTstamp == null) throw new IllegalArgumentException("The minTstamp argument is required");
        if (maxTstamp == null) throw new IllegalArgumentException("The maxTstamp argument is required");
        EntityManager em = Detection.entityManager();
        TypedQuery<Detection> q = em.createQuery("SELECT o FROM Detection AS o WHERE o.tstamp BETWEEN :minTstamp AND :maxTstamp", Detection.class);
        q.setParameter("minTstamp", minTstamp);
        q.setParameter("maxTstamp", maxTstamp);
        return q;
}

何が問題を引き起こす可能性がありますか?

4

1 に答える 1

0

私はついに謎の解決策を見つけましたが、結局のところ、問題は JPA とは何の関係もありませんでした。

問題は、永続化レイヤーへの呼び出しが、次のマッピングを使用して Rest サービス コントローラー内に挿入されたことです。

@ResponseBody
@RequestMapping(value="/detections", method=RequestMethod.GET, params="from, to" )
public Object getDetectionsInRange(
        @RequestParam(required=true) @DateTimeFormat(pattern="yyyy-MM-dd HH:mm") final Date from,
        @RequestParam(required=true) @DateTimeFormat(pattern="yyyy-MM-dd HH:mm") final Date to
        ) 
{
    ...
    List<Detection> detections = Detection.findDetectionsByTstampBetween(from, to).getResultList(); 
    ...
}

params=の引数の定義にエラーがありました@RequestMapping。正しい形式は次のとおりです。

@RequestMapping(value="/detections", method=RequestMethod.GET, params={"from", "to"}  )

このエラーにより、 のコントローラ メソッドの別のバージョンが発生しました/detections。この 2 番目のバージョンでは、Hibernate で間違った SQL を生成するように見える別のファインダー メソッドを呼び出しました。

@ResponseBody
@RequestMapping(value="/detections", method=RequestMethod.GET  )
public Object getDetections(
        @RequestParam(required=false, defaultValue="0") int days,
        @RequestParam(required=false, defaultValue="0") int hours,
        @RequestParam(required=false, defaultValue="0") int minutes
        ) 
{
    ...
    List<Detection> detections = Detection.findDetectionsByTstampGreaterThanEquals( ... ).getResultList(); 
    ...
}
于 2015-04-15T13:03:33.020 に答える