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

问题描述 投票:17回答: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_time的实体,并期望数据库将当前时间填充为默认值。

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'并让数据库设置默认值。

欢迎任何帮助!

致克劳斯

java postgresql orm jpa jpa-2.0
10个回答
17
投票

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

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


-1
投票

你可以用这种方式:

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

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


20
投票

使用注释

@Column(insertable = false)

将阻止在sql中生成的值。


6
投票

在Annotation @Column中,将属性insertable设置为false,如下所示:

`@Column(name="system_time", insertable = false)`

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


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();

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


1
投票

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

@Column(name="system_time")
private Date systemTime = new Date();

0
投票

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

@Temporal(TemporalType.TIMESTAMP)
@Column(name="CREATION_TIME", 
        columnDefinition="TIMESTAMP DEFAULT SYSTIMESTAMP",
        nullable=false,
        insertable=false,
        updatable=false)
private Date creationTime;

0
投票

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

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

how to avoid the null property in insert or update


-1
投票

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


-1
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.