【问题标题】:Postgres Serial not-null constraintPostgres 串行非空约束
【发布时间】:2015-08-03 09:12:16
【问题描述】:

我有以下数据库表:

CREATE TABLE company
(
  id serial NOT NULL,
  name character varying(50),
  activestatus boolean,
  address bigint,
  remarks character varying(1024),
  revision integer
)

CREATE TABLE company_version
(
  id serial NOT NULL,
  company_id integer,
  name character varying(50),
  revision serial NOT NULL,
  revision_previous integer,
  revision_timestamp timestamp without time zone,
  revision_comment character varying(100),
  revision_userid character varying(50)
)

在公司表上,我有一个在插入后执行的触发器。

INSERT INTO company_version (company_id,name,revision_previous,revision_timestamp,revision_comment,revision_userid)
                                VALUES (NEW.id, NEW.name, (SELECT MAX(revision) FROM company_version),CURRENT_TIMESTAMP,'Inserted in application','The application')
                                RETURNING revision into revision_param;
            UPDATE company SET revision = revision_param WHERE id = NEW.id;

当我插入一个新公司时,company_version 表会按原样添加。但是当我在 Java 中创建一个新的 CompanyVersion 对象并让它通过 JPA 持续存在时,它会在“修订”列上给我一个非空约束错误。

org.postgresql.util.PSQLException: ERROR: null value in column "revision" violates not-null constraint

这是我尝试执行的代码:

final CompanyVersion cv = new CompanyVersion();
cv.setCompanyId(c);
cv.setName(c.getName());

cv.setRevisionTimestamp(new Date());
cv.setRevisionComment("Updated in application");
cv.setRevisionUserid("The application");
cv.setRevisionPrevious(this.findLatestVersion(c));

this.persist(cv);

这是我的 CompanyVersion 对象:

public class CompanyVersion {

    private static final long serialVersionUID = 1L;
    @Id
    @SequenceGenerator(name = "company_version_id_seq", sequenceName = "company_version_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "company_version_id_seq")
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Size(max = 50)
    @Column(name = "name")
    private String name;
    @OneToMany(mappedBy = "revisionPrevious", fetch = FetchType.LAZY)
    private List<CompanyVersion> previousRevisionList;
    @JoinColumn(name = "revision_previous", referencedColumnName = "revision")
    @ManyToOne(fetch = FetchType.LAZY)
    private CompanyVersion revisionPrevious;
    @JoinColumn(name = "company_id", referencedColumnName = "id")
    @ManyToOne(fetch = FetchType.LAZY)
    private Company companyId;
    @Column(name = "revision_timestamp")
    @Temporal(TemporalType.TIMESTAMP)
    private Date revisionTimestamp;
    @Size(max = 100)
    @Column(name = "revision_comment")
    private String revisionComment;
    @Size(max = 50)
    @Column(name = "revision_userid")
    private String revisionUserid;
    @Basic(optional = false)
    @Column(name = "revision")
    protected Integer revision;

    public CompanyVersion() {
    }

    public CompanyVersion(Integer id) {
        this.id = id;
    }

    public CompanyVersion(Integer id, int revision) {
        this.id = id;
        this.revision = revision;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<CompanyVersion> getPreviousRevisionList() {
        return previousRevisionList;
    }

    public void setPreviousRevisionList(List<CompanyVersion> previousRevisionList) {
        this.previousRevisionList = previousRevisionList;
    }

    public CompanyVersion getRevisionPrevious() {
        return revisionPrevious;
    }

    public void setRevisionPrevious(CompanyVersion revisionPrevious) {
        this.revisionPrevious = revisionPrevious;
    }

    public Company getCompanyId() {
        return companyId;
    }

    public void setCompanyId(Company companyId) {
        this.companyId = companyId;
    }

    public Date getRevisionTimestamp() {
        return revisionTimestamp;
    }

    public void setRevisionTimestamp(Date revisionTimestamp) {
        this.revisionTimestamp = revisionTimestamp;
    }

    public String getRevisionComment() {
        return revisionComment;
    }

    public void setRevisionComment(String revisionComment) {
        this.revisionComment = revisionComment;
    }

    public String getRevisionUserid() {
        return revisionUserid;
    }

    public void setRevisionUserid(String revisionUserid) {
        this.revisionUserid = revisionUserid;
    }

    public Integer getRevision() {
        return revision;
    }

    public void setRevision(Integer revision) {
        this.revision = revision;
    }
}

我已经尝试在修订版中添加 @SequenceGenerator@GeneratedValue 注释,但到目前为止没有运气(由于某种原因,@GeneratedValue 不允许在 2 个字段上使用)。

我认为我不应该选择最新版本,添加一个并在我的支持 bean 中执行 cv.setRevision() 方法。但到目前为止,我认为这是唯一的解决方案。

那么如何让revision 字段自动插入呢?

【问题讨论】:

  • 您需要找到一种方法,通过不在INSERT 语句中列出revision 列来告诉您的混淆层(又名ORM)不提供任何值,或者告诉它使用在生成的insert 语句中使用DEFAULT 而不是NULL
  • @a_horse_with_no_name 所以在我的情况下,我需要告诉 EclipseLink 在插入时省略 revision 字段?

标签: java postgresql jpa


【解决方案1】:

更改了我的 JPA 实体
@Basic(optional = false)
@Column(name = "revision")
protected Integer revision;

@Basic(optional = false)
@Column(name = "revision", insertable = false)
protected Integer revision;

成功了!

【讨论】:

  • insertable = false 为我工作,使用 Postgresql10
猜你喜欢
  • 2020-02-10
  • 2020-11-16
  • 2021-09-27
  • 2021-08-21
  • 2017-05-24
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 2016-07-12
相关资源
最近更新 更多