
本文旨在解决在使用 Spring Data JPA 时,数据库表字段的默认值被覆盖的问题。我们将探讨 JPA 默认行为,并提供使用 `@Generated` 注解来确保数据库默认值生效的解决方案。通过本文,你将了解如何在 Spring Data JPA 应用中正确处理数据库默认值,避免数据不一致的问题。
在使用 Spring Data JPA 进行数据库操作时,有时会遇到数据库表字段定义的默认值没有生效,而是被 JPA 覆盖的情况。这通常是因为 JPA 默认情况下会显式地插入所有列,从而忽略了数据库层面的默认值设置。本文将介绍如何解决这个问题,确保数据库默认值能够正确填充。
问题分析
当使用类似如下的 SQL 创建表时,CREATED_ON 和 CREATED_BY 列都定义了默认值:
CREATE TABLE CONFIGSERVER.PROPERTIES ( ID NUMBER GENERATED ALWAYS AS IDENTITY ( START WITH 1 CACHE 20 ) , APPLICATION VARCHAR2 (4000) , PROFILE VARCHAR2 (4000) , LABEL VARCHAR2 (4000) , PROP_KEY VARCHAR2 (4000) NOT NULL, VALUE VARCHAR2 (4000) NOT NULL, CREATED_ON TIMESTAMP DEFAULT SYSDATE, CREATED_BY VARCHAR2 (100) DEFAULT COALESCE( REGEXP_SUBSTR(SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER'),'^[^:]*'), SYS_CONTEXT('USERENV','SESSION_USER')), UPDATED_ON TIMESTAMP , UPDATED_BY VARCHAR2 (100)) LOGGING;
如果在不使用 JPA 的情况下,直接使用 SQL 插入数据,这些默认值会被正确填充。但如果使用 Spring Data JPA,则可能会发现 CREATED_ON 和 CREATED_BY 的默认值没有生效。
解决方案:使用 @Generated 注解
为了解决这个问题,可以使用 JPA 的 @Generated 注解。这个注解可以指示 JPA 在插入数据时,不要显式地插入该列,而是从数据库中读取该列的值。
修改实体类 Properties,在 createdOn 和 createdBy 字段上添加 @Generated 注解,并设置 insertable = false:
package com.example.configcrud.model;import javax.persistence.*;import java.sql.Timestamp;import org.hibernate.annotations.Generated;import org.hibernate.annotations.GenerationTime;@Entity@Table(name = "properties")public class Properties { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @Column(name = "application") private String application; @Column(name = "profile") private String profile; @Column(name = "label") private String label; @Column(name = "prop_key") private String propKey; @Column(name = "value") private String value; @Generated(GenerationTime.INSERT) @Column(name = "created_on", updatable = false, insertable = false) private Timestamp createdOn; @Generated(GenerationTime.INSERT) @Column(name = "created_by", updatable = false, insertable = false) private String createdBy; public Properties(String application, String profile, String label, String propKey, String value) { this.application = application; this.profile = profile; this.label = label; this.propKey = propKey; this.value = value; } public Properties() { } public String getApplication() { return application; } public void setApplication(String application) { this.application = application; } public String getProfile() { return profile; } public void setProfile(String profile) { this.profile = profile; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public String getPropKey() { return propKey; } public void setPropKey(String propKey) { this.propKey = propKey; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public Timestamp getCreatedOn() { return createdOn; } public Timestamp setCreatedOn() { return createdOn; } public String getCreatedBy() { return createdBy; } public String setCreatedBy() { return createdBy; } @Override public String toString() { return "Properties [id=" + id + ", " + "application=" + application + ", " + "profile=" + profile + ", " + "label=" + label + "propkey=" + propKey + "value=" + value + "CreatedOn=" + createdOn + "CreatedBy=" + createdBy + "]"; }}
代码解释:
@Generated(GenerationTime.INSERT): 指定在插入时生成该字段的值。GenerationTime.INSERT 表示在插入时从数据库读取值。@Column(name = “created_on”, updatable = false, insertable = false):name = “created_on”: 指定数据库表中的列名。updatable = false: 禁止更新该字段。insertable = false: 禁止插入该字段,让数据库使用默认值。
注意事项:
依赖: 确保添加了 org.hibernate 的依赖,因为 @Generated 注解来自于 Hibernate。如果使用的是其他 JPA 实现,需要使用对应的注解。
org.hibernate hibernate-core
updatable = false: 通常还需要设置 updatable = false,以防止在更新操作时覆盖数据库中的值。
insertable = false: insertable = false 是关键,它告诉 JPA 不要尝试插入这个字段,从而允许数据库使用默认值。
总结
通过使用 @Generated 注解并设置 insertable = false,可以有效地解决 Spring Data JPA 覆盖数据库默认值的问题。这种方法确保了在插入数据时,数据库能够使用其自身定义的默认值,从而维护数据的一致性和准确性。在实际开发中,应该根据具体情况选择合适的策略来处理数据库默认值,避免潜在的数据问题。
以上就是Spring Data JPA 忽略数据库默认值问题及解决方案的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/22847.html
微信扫一扫
支付宝扫一扫