0

Apache CXF(バージョン2.5.2)を使用して、データベーステーブルのレコードの追加、更新、削除、単一およびリストのクエリを実行するRESTサービスを実装しています。永続層でOpenJPA(バージョン2.2.0)を使用しています。

例として、同じ名前のエンティティクラスにマップされたComplaintという名前のテーブルがあります。苦情エンティティは次のようになります。

import java.io.Serializable;
import java.sql.Timestamp;  

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table; 



/**
 * The persistent class for the "Complaint" database table.
 * 
 */
@Entity
@Table(name = "Complaint")
@NamedQueries({
        @NamedQuery(name = "cmplById", query = "SELECT c FROM Complaint c WHERE c.id = ?1"),
        @NamedQuery(name = "cmplBySearchCriteria", query = "SELECT c FROM Complaint c WHERE  c.status = ?1 AND c.category = ?2 AND c.location = ?3 AND "
                + "c.reportDate BETWEEN ?4 AND ?5 ORDER BY c.id DESC")

})

public class Complaint implements Serializable {
    private static final long serialVersionUID = 1L;

    private Integer id;

    private String description;

    private String location;

    private Timestamp reportDate;

    private String reportedBy;

    private String status;

    private String category;

    public Complaint() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Id", nullable = false)
    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name = "Description")
    public String getDescription() {
        return this.description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Column(name = "Location")
    public String getLocation() {
        return this.location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    @Column(name = "ReportDate", nullable = false)
    public Timestamp getReportDate() {
        return this.reportDate;
    }

    public void setReportDate(Timestamp reportDate) {
        this.reportDate = reportDate;
    }

    @Column(name = "ReportedBy", nullable = false)
    public String getReportedBy() {
        return this.reportedBy;
    }

    public void setReportedBy(String reportedBy) {
        this.reportedBy = reportedBy;
    }

    @Column(name = "Status", nullable = false)
    public String getStatus() {
        return this.status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    @Column(name = "Category", nullable = false)
    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

}

データを返す2つのクエリ操作に関連する問題を除いて、すべてのサービスは正常に機能しています。

操作getComplaintByIdgetAllComplaint現在、データベースで使用可能な値を持つすべてのフィールドを持つエンティティを返しますが、idフィールドはnullとして返されます。名前付きクエリ、ネイティブSQL、エンティティマネージャーのfindメソッドの3つの方法で、これらのメソッドのクエリを構造化してみました。これらはすべて同じ結果になります。

テストするために、nullチェックに基づいてidフィールドの値を設定しようとすると、idフィールドの値がfinalであると言って許可されません。

MySQLとPostgresデータベースの両方に対してコードを実行しても同じ結果が見つかりました。クエリメソッドの1つのコードを次に示します。

public Complaint getComplaintById(Integer id) {     
        Complaint cmpl;

    //case-1: The NamedQueries as defined in the entity class Complaint --> @NamedQuery(name="cmplById", query="SELECT c FROM Complaint c WHERE c.id = ?1")
    //Query query = em.createNamedQuery("cmplById");

    //case-2: using NativeQuery
    //Query query = em.createNativeQuery("SELECT * FROM COMPLAINT WHERE ID=?1", Complaint.class);

    //query.setParameter(1, id);
    //cmpl = (Complaint) query.getSingleResult();  

    //case-3: using find method on entity manager        
    cmpl = em.find(Complaint.class, id);

    System.out.println("id = " + cmpl.getId());//returning null, but get method on all other fields returning their values as expected. 

    return cmpl; 
}

ログには、OpenJPAが実行しているクエリステートメントに他のすべてのフィールドが含まれていることがわかりますが、以下のようにselect句のidフィールドは含まれていません。

1720 ramsjpa TRACE ["http-bio-8080"-exec-3]openjpa.jdbc.SQL-prepstmntの実行14227847SELECTt0.Category、t0.Description、t0.Location、t0.ReportDate、t0.ReportedBy、t0.Status FROM苦情t0WHEREt0.Id =?[params =?]

私は初めてCXFとOpenJPAを使用していますが、基本的な間違いを犯している可能性があります。

4

1 に答える 1

0

データベースに挿入した直後にgetComplaintByIdを呼び出している可能性がありますか? その場合、問題はId フィールドにGenerationType.IDENTITYを使用することに関連している可能性があります。GenerationType.IDENTITY では、ID は行が挿入されるまでデータベースによって割り当てられないため、コミット後またはフラッシュ呼び出し後までオブジェクトで ID を取得できません。(参照: http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Identity_sequencing )

そのため、ID で苦情を検索する前に、次のことを行う必要があると思います。

Complaint complaint = new Complaint();
// Fill in your complaint fields...
em.persist(complaint);
em.flush();
em.getTransaction().commit();
于 2012-04-19T16:41:00.003 に答える