@ColumnDefault 的 HIbernate 列不能为空
Posted
技术标签:
【中文标题】@ColumnDefault 的 HIbernate 列不能为空【英文标题】:HIbernate Column with @ColumnDefault cannot be null 【发布时间】:2018-09-11 13:07:26 【问题描述】:我的应用程序通过 Spring Boot 使用休眠。
我已经创建了一个这样的表:
public class TopicSubscriberMap implements Serializable
@ColumnDefault(value="'pending'")
@Column(nullable=false)
private String status;
...
表在mysql中创建如下:
mysql> desc topic_subscriber_map;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| status | varchar(255) | NO | | pending | |
+---------------+--------------+------+-----+---------+-------+
像这样保存表格:
TopicSubscriberMap tsm = new TopicSubscriberMap();
tsm = mapRepository.save(tsm);
我收到一个错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'status' cannot be null
如果我使该字段可以为空,那么虽然表正在保存,但在数据库中,
+--------+
| status |
+--------+
| NULL |
+--------+
为什么@ColumnDefault 不起作用?我的错在哪里?
编辑: 当我删除 @ColumnDefault 并将列声明为
private String status = "pending"
那么虽然默认值确实有效,但表架构显示:
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| status | varchar(255) | NO | | NULL | |
+---------------+--------------+------+-----+---------+-------+
如何使默认值起作用并在表架构中显示它?
【问题讨论】:
set default value in hibernate此链接将有助于解决您的问题 【参考方案1】:因此,您在这里使用了 2 种不同的设置默认值的方法:通过 DB 和通过 Java。两种方法都不会相互协调,如果配置了另一种方法,则一种方法不受影响。我会解释的。
您对@ColumnDefault
使用的第一种方法是DB 方法。使用@Column
的columnDefinition
属性可以实现相同的行为。在这里,JPA 只是将此值添加到 DB 中字段的列定义中。但是,Hibernate 在准备查询时不考虑 DB 定义,并将空值从 Java 对象转录到其准备好的 SQL 查询中,从而导致查询执行时出现MySQLIntegrityConstraintViolationException
。更多信息在这里:Hibernate Guide
您使用的第二种方法依赖于 Java 初始化。当您调用new TopicSubscriberMap();
时,您的实体对象获得了默认值。但是您的数据库不知道或不关心它,因为它的列定义没有受到影响。
解决方案
如果您想在 DB 上设置默认值并能够在应用程序中使用它们,您可以使用 Hibernate 的 @DynamicInsert
注释
@DynamicInsert
public class TopicSubscriberMap implements Serializable
@ColumnDefault(value = "pending")
// alternately @Column(columnDefinition = "VARCHAR(255) DEFAULT 'pending'")
private String status;
...
这将解决您的两个问题,尽管在某些情况下它会带来自己的一组性能问题,在此线程中谈到:Why does Hibernate set dynamic insert=false by default
【讨论】:
以上是关于@ColumnDefault 的 HIbernate 列不能为空的主要内容,如果未能解决你的问题,请参考以下文章
6.Spring+Struts+Hibernat注解方式整合