2012-04-18 5 views
0

Apache CXF(バージョン2.5.2)を使用して、データベーステーブルのレコードの追加、更新、削除、クエリのシングルとリストを行うRESTサービスを実装しています。私は、持続層でOpenJPA(バージョン2.2.0)を使用しています。OpenJPA - インスタンスのidフィールドがクエリでnullを返す

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

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フィールドがヌルとして戻っています。これらのメソッドでは、名前付きクエリを使用し、ネイティブSQLを使用し、エンティティ・マネージャでfindメソッドを使用するという3つの方法でこれらのメソッドのクエリを構造化しようとしました。

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を実行中14227847 SELECT t0.Category、t0.Description、t0.Location、t0.ReportDate、t0.ReportedBy、 t0.Status FROM苦情t0 WHERE t0.Id =? [params =?]

私は初めてCXFとOpenJPAで作業しています。私は基本的な間違いをしている可能性があります。

+0

あなたのエンティティクラスの実際のソースが含まれていませんでした。あなたの質問にそれを加えてください。このエンティティの 'id'フィールドに何らかの機会があったとしたら? – Perception

+0

@Perceptionのコードを編集するときに 'getId()'の定義を含めるのを忘れないでください。素早い対応のおかげで、エンティティクラスを追加しました。idフィールドはfinalとしてマークされていません。 – user1340182

+0

エンティティをどのように強化していますか? – Rick

答えて

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(); 
関連する問題