避免通过JPA向数据库表插入'null'值

java postgresql orm jpa jpa-2.0

32153 观看

10回复

我从JPA2开始,到目前为止感觉相当舒适。但是,当使用默认值为NON NULL数据库字段保留具有null属性值的实体时,我遇到了问题。

我希望能够将实体属性保留为null并让数据库插入默认值。

我目前的设置是使用PostgreSQL的openJPA。

我有这个VERSION数据库表(Vorgabewert =默认值):


     Spalte     |             Typ             |         Attribute
----------------+-----------------------------+----------------------------
 status_        | smallint                    | not null Vorgabewert 0
 time_          | timestamp without time zone | not null
 system_time    | timestamp without time zone | not null Vorgabewert now()
 version        | character varying(20)       | not null
 activationtime | timestamp without time zone |
 importtime     | timestamp without time zone |

我有一个实体(Java DTO),它通过xml配置映射数据库字段('status'除外)。

我希望我可以插入一个没有system_timeset 的实体,并期望数据库将当前时间填充为默认值。

JPA构造以下SQL-Query:

INSERT INTO public.version (version, activationtime, importtime, system_time, time_) VALUES (?, ?, ?, ?, ?) [params=?, ?, ?, ?, ?]

和Postgres作出反应:

FEHLER: NULL-Wert in Spalte »system_time« verletzt Not-Null-Constraint (对不起德语,但此消息表示'system_time'上的Not-Null-Constraint违规)。

那我该怎么办?这是JPA还是数据库问题。我是否可以配置JPA以从INSERT SQL语句中排除空属性。

我希望能够在我的实体中设置'system_time'或让它为'null'并让数据库设置默认值。

欢迎任何帮助!

致克劳斯

作者: FrVaBe 的来源 发布者: 2019 年 7 月 18 日

回应 (10)


17

决定

我不会将数据库中的默认值与JPA结合使用。您必须在插入后读取实体,否则您将在实体状态和db状态之间不匹配。

在这里选择实用的方法并初始化java中的所有值。从来没有听说过告诉JPA / Hibernate在插入/更新中省略空值的方法。

作者: bert 发布者: 23.12.2010 09:40

20

使用注释

@Column(insertable = false)

将阻止在sql中生成的值。

作者: OrangeDog 发布者: 23.12.2010 10:58

6

在Annotation @Column中,将atribute可插入为false,如下所示:

`@Column(name =“system_time”,insertable = false)`

或者,如果您需要检查值是否为NULL,则在表上进行“插入前触发”。

作者: Jorge Mario Samayoa 发布者: 15.04.2013 09:30

2

从文档:columnDefinition:为列生成DDL时使用的SQL片段。

通过使用columnDefinition,您可以根据需要指定约束。

   @Column(name="COLUMN_NAME", 
   columnDefinition="DATE DEFAULT CURRENT_DATE",table="TABLE_NAME")

否则,您可以尝试初始化实体本身中的字段以摆脱这种情况。

    @Column(name = "somedate", nullable = false)
    private Date someDate = new Date();

因此,默认情况下,如果您未设置当前日期,则会插入当前日期。

作者: Nayan Wadekar 发布者: 22.12.2010 12:20

1

我找到了一个简单的解决方案:在pojo中定义一个默认值。

@Column(name="system_time")
private Date systemTime = new Date();
作者: xeon_pan 发布者: 30.08.2018 11:08

0

我使用它(针对Oracle数据库):

@Temporal(TemporalType.TIMESTAMP)
@Column(name="CREATION_TIME", 
        columnDefinition="TIMESTAMP DEFAULT SYSTIMESTAMP",
        nullable=false,
        insertable=false,
        updatable=false)
private Date creationTime;
作者: Jim Tough 发布者: 16.02.2017 08:13

0

你可以通过在@column注释中添加nullable = false来避免null属性。像这样

@Column(name = "muColumn", nullable = false)

如何避免插入或更新中的null属性

作者: user9247837 发布者: 21.01.2018 03:49

-1

只需从INSERT语句中的列中省略system_time即可。

作者: a_horse_with_no_name 发布者: 22.12.2010 11:24

-1

我不知道在JPA中有什么方法可以做到这一点。

但是您可以向数据库添加一个触发器,该触发器捕获尝试将NULL插入到相关列中,并重写插入以插入默认值?实质上,您将默认生成行为完全移至数据库中,而不是在JPA和数据库之间拆分。

然而,正如伯特在他的回答中指出的那样,这会使对象和数据库不一致,这几乎肯定是一个糟糕的想法。

作者: Tom Anderson 发布者: 23.12.2010 10:09

-1

你可以用这种方式:

@JoinColumn(name = "team_id", nullable = false)

使用这种方式,JPA将检查NULL值。

作者: sushil 发布者: 17.07.2011 04:16
32x32