首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >实例的OpenJPA - id字段在查询时返回null。

实例的OpenJPA - id字段在查询时返回null。
EN

Stack Overflow用户
提问于 2012-04-18 04:07:55
回答 1查看 839关注 0票数 0

我正在使用Apache (Version2.5.2)实现REST服务,这些服务可以在数据库表中添加、更新、删除、查询单个记录和记录列表。我在持久性层中使用OpenJPA (Version2.2.0)。

举个例子,我有一个名为投稿的表,映射到一个同名的实体类。申诉实体与此类似:

代码语言:javascript
运行
复制
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;
    }

}

除了与返回数据的两个查询操作相关的问题外,所有服务都正常工作。

操作getComplaintByIdgetAllComplaint当前返回实体,其中包含数据库中有值的所有字段,,但id字段返回为null。我尝试用三种方式构造这些方法中的查询--使用命名查询、使用原生sql和在实体管理器上使用find方法--所有这些都得到了相同的结果。

为了测试,如果我尝试基于空检查来设置id字段的值,它就不允许我,它说id字段的值是最终的。

我发现了对MySQL和Postgres数据库运行代码的相同结果。以下是查询方法之一的代码。

代码语言:javascript
运行
复制
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字段,如下所示。

1720ramsjpa跟踪"http-bio-8080"-exec-3 openjpa.jdbc.SQL -执行prepstmnt 14227847,选择t0 . TRACE,t0. t0.Description,t0. t0.Location,t0. t0.ReportDate,t0.t0.ReportDate,t0. t0.ReportedBy,t0. t0.Status FROM t0,其中t0.Id =?params=?

我是第一次使用CXF和OpenJPA,我可能犯了一个基本的错误,所有的帮助都很感激。

EN

回答 1

Stack Overflow用户

发布于 2012-04-19 16:41:00

您是否可能在将getComplaintById插入数据库后立即调用它?如果是这样,那么您的问题可能与在Id字段中使用GenerationType.IDENTITY有关。使用GenerationType.IDENTITY时,由于数据库在插入行之前不会分配id,所以在提交或刷新调用之后才能在对象中获得id。(参考:http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Identity_sequencing)

因此,我认为,在试图通过Id查找投诉之前,您需要做以下几点:

代码语言:javascript
运行
复制
Complaint complaint = new Complaint();
// Fill in your complaint fields...
em.persist(complaint);
em.flush();
em.getTransaction().commit();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10202616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档