【问题标题】:JPA EclipseLink: handle default valueJPA EclipseLink:处理默认值
【发布时间】:2018-10-10 09:07:24
【问题描述】:

我有以下列定义:

@Column(name="active", nullable=false, columnDefinition="BOOLEAN DEFAULT FALSE"
private Boolean active;

在 Postgres 数据库中,active 列定义为 BOOLEAN NOT NULL DEFAULT FALSE

但是当我插入一条新记录时,没有设置active,EclipseLink 会为该字段生成一个null 值,并且插入语句显然失败,因为 Postgres 不允许null 列的null 值。

我做错了什么?

好吧,如果我将我的字段定义为

private boolean active;

然后我将间接将该字段设置为false。但是我不能在Date 字段中使用这个技巧。所以,我正在寻找一种适用于所有列类型的解决方案。

【问题讨论】:

  • JPA 本身并不支持此功能,但这是您应该做的 - stackoverflow.com/a/28208792/4116955
  • 我建议在我的帖子中给出这个答案中的“非数据库便携解决方案”。但是,它仅适用于boolean。对于其他类型,我只能使用“面向Java的解决方案”。
  • 我不明白columnDefinition 是如何工作的。没有效果的情况下,我为什么要把它放在java代码中?实际上,我不理解“非数据库可移植解决方案”——它之所以有效,是因为它们使用boolean,而不是Boolean,因此它们始终具有默认false。这与“面向 Java 的解决方案”相同。如果这个想法是注释很重要 - 我不明白这是如何工作的。

标签: postgresql jpa eclipselink default-value


【解决方案1】:

columnDefinition 仅用于创建 DDL,并且可以是特定于数据库的。如果你使用它,你可能会在切换数据库时遇到问题。

使用原始类型确保值不为空,并且在没有显式定义值的情况下,使用原始类型的默认值。但是,您也可以通过分配它们来定义非原始值的默认值:private Boolean active = false; 这也适用于Date

当您需要复杂的默认值时,您可以使用PrePersist 注解:

    @PrePersist
    public void setDefaultValues() {
        if (active == null) {
            active = false;
        }
        if (value == null) {
           //do complex stuff
        }
    }

【讨论】:

    【解决方案2】:

    如果你从不打算设置属性,你可以使用@Column (insertable = false),如果你设置了一个值,无论如何都会被忽略。 这是 Date 上非常常见的设置,例如

    @Column(nullable = false, insertable = false, updatable = false, columnDefinition = "timestamp not null default CURRENT_TIMESTAMP")
        @Temporal(TemporalType.TIMESTAMP)
        private Date systemDate;
    

    【讨论】:

      猜你喜欢
      • 2015-04-23
      • 1970-01-01
      • 2011-03-13
      • 2013-09-24
      • 1970-01-01
      • 2013-12-03
      • 2018-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多