如何使用 Hibernate 设置默认实体属性值

如何在 Hibernate 字段中设置默认值?

322732 次浏览

为字段设置默认值怎么样?

private String _foo = "default";


//property here
public String Foo

如果它们传递了一个值,那么它将被覆盖,否则,您将得到一个缺省值。

如果需要一个真正的数据库默认值,请使用 columnDefinition:

@Column(name = "myColumn", nullable = false, columnDefinition = "int default 100")

请注意,columnDefinition中的字符串是依赖于数据库的。另外,如果选择此选项,则必须使用 dynamic-insert,因此 Hibernate在插入时不包括具有 null值的列。否则,谈论违约就无关紧要了。

但是,如果您不想要数据库默认值,而只想要 Java 代码中的默认值,那么只需像这样初始化变量 -private Integer myColumn = 100;

一种解决方案是让 getter 检查您正在处理的值是否为 null (或者它的非初始化状态是什么) ,如果它等于这个值,只需返回默认值:

public String getStringValue(){
return (this.stringValue == null) ? "Default" : stringValue;
}

如果你想在数据库里做:

设置数据库中的默认值(sql 服务器示例) :

ALTER TABLE [TABLE_NAME] ADD  CONSTRAINT [CONSTRAINT_NAME]  DEFAULT (newid()) FOR [COLUMN_NAME]

映射休眠文件:

    <hibernate-mapping ....
...
<property name="fieldName" column="columnName" type="Guid" access="field" not-null="false"  insert="false" update="false"  />
...

关键是 insert = “ false”update = “ false”

您可以使用 @PrePersist注释并在预持久化阶段设置默认值。

差不多是这样:

//... some code
private String myProperty;
//... some code


@PrePersist
public void prePersist() {
if(myProperty == null) //We set default value in case if the value is not set yet.
myProperty = "Default value";
}


// property methods
@Column(nullable = false) //restricting Null value on database level.
public String getMyProperty() {
return myProperty;
}


public void setMyProperty(String myProperty) {
this.myProperty= myProperty;
}

此方法不依赖于 Hibernate 下的数据库类型/版本。

<property name="age" type="integer">
<column name="age" not-null="false" default="null" />
</property>

我搜索了这个问题,找到了很多关于 column 默认值的答案。如果你想使用 SQL Table 中定义的默认值,那么在@Column 注释中使用 < em > “ insert table = false”。插入式的

@ Column (name = columnName,length = longthOfColumn,insert table = false)

如果您使用的是 columnDefinition,那么@Column 注释可能不起作用,因为它是依赖于数据库的。

在使用 Oracle 时,我试图为 Enum 插入一个默认值

我发现以下方法最有效。

@Column(nullable = false)
@Enumerated(EnumType.STRING)
private EnumType myProperty = EnumType.DEFAULT_VALUE;

您可以使用 java 类构造函数来设置默认值。例如:

public class Entity implements Serializable{
private Double field1
private Integer field2;
private T fieldN;


public Entity(){
this.field1=0.0;
this.field2=0;
...
this.fieldN= <your default value>
}


//Setters and Getters
...


}

使用 @ColumnDefault()注释。

使用 hibernate 注释。

@ColumnDefault("-1")
private Long clientId;

如果表已经存在以使更改生效,则重新创建该表。

如果要根据数据库设置默认值,只需设置 @Column( columnDefinition = "int default 1")

但是如果你想在你的 java 应用程序中设置一个默认值,你可以像这样在 class 属性上设置它: private Integer attribute = 1;

我正在与冬眠5和 Postgres 工作,这对我起作用。

@Column(name = "ACCOUNT_TYPE", ***nullable***=false, columnDefinition="varchar2 default 'END_USER'")
@Enumerated(EnumType.STRING)
private AccountType accountType;

使用表中任意列的默认值。那么您必须将 @DynamicInsert定义为 true,否则就只能定义 @DynamicInsert。因为 hibernate 默认采用 true。 考虑一下给定的例子:

@AllArgsConstructor
@Table(name = "core_contact")
@DynamicInsert
public class Contact implements Serializable {


@Column(name = "status", columnDefinition = "int default 100")
private Long status;


}

默认实体属性值

如果要设置默认实体属性值,则可以使用默认值初始化实体字段。

例如,可以将默认的 createdOn实体属性设置为当前时间,如下所示:

@Column(
name = "created_on"
)
private LocalDateTime createdOn = LocalDateTime.now();

使用 JPA 的默认列值

如果使用 JPA 和 Hibernate 生成 DDL 模式,尽管不推荐这样做,但是可以使用 JPA @Column注释的 columnDefinition属性,如下所示:

@Column(
name = "created_on",
columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP"
)
@Generated(GenerationTime.INSERT)
private LocalDateTime createdOn;

之所以需要 @Generated注释,是因为我们希望指示 Hibernate 在持久化上下文刷新之后重新加载实体,否则,数据库生成的值将不会与内存中的实体状态同步。

与其使用 columnDefinition,不如使用 Flyway 这样的工具并使用 DDL 增量迁移脚本。这样,您将在脚本中而不是在 JPA 注释中设置 DEFAULTSQL 子句。

使用 Hibernate 的默认列值

如果在 Hibernate 中使用 JPA,那么也可以使用 @ColumnDefault注释,如下所示:

@Column(name = "created_on")
@ColumnDefault(value="CURRENT_TIMESTAMP")
@Generated(GenerationTime.INSERT)
private LocalDateTime createdOn;

使用 Hibernate 默认的 Date/Time 列值

如果在 Hibernate 中使用 JPA 并希望设置创建时间戳,那么可以使用 @CreationTimestamp注释,如下所示:

@Column(name = "created_on")
@CreationTimestamp
private LocalDateTime createdOn;

假设我们有一个包含子实体的实体。

在实体上使用 insertable = false, updatable = false可以防止实体创建新的子实体和默认 DBMS 值之前。但问题是,我们必须始终使用默认值,或者如果我们需要实体包含另一个不是默认的子实体,我们必须尝试在运行时将这些注释更改为 insertable = true, updatable = true,所以它似乎不是一个好的路径。

如果在所有列 insertable = false, updatable = false中使用子实体更有意义,那么在子实体内部不会创建更多的子实体,而不管我们使用什么方法(对于 @DynamicInsert,这是不必要的)

插入默认值可以通过各种方式完成,比如使用构造函数或 setter 的 默认实体属性值。其他方法,比如将 JPA 与 column Definition 一起使用,缺点是它们在默认情况下插入 null,而 DBMS 的默认值不在前面。


使用 DBMS 插入默认值,并可选地使用 Hibernate

但是使用 @DynamicInsert时,当我们想要插入一个具有默认值的子实体时,我们避免向 db 发送一个 null,反过来,我们允许插入具有默认值以外的值的子实体。

对于插入,这个实体是否应该使用动态 sql 生成,其中只有非空列在准备好的 sql 语句中被引用?

根据以下需要:

  • 该实体不负责创建新的子实体。
  • 插入实体时,子实体是 DBMS 中定义为默认的实体。
  • 创建一个子实体的可能性,该子实体的 UUID 不是默认的。

DBMS : PostgreSQL | 注意用词: Kotlin

@Entity
@Table(name = "entity")
@DynamicInsert
data class EntityTest(
@Id @GeneratedValue @Column(name = "entity_uuid") val entityUUID: UUID? = null,


@OneToOne(cascade = [CascadeType.ALL])
@JoinColumn(name = "subentity_uuid", referencedColumnName = "subentity_uuid")
var subentityTest: SubentityTest? = null
) {}


@Entity
@Table(name = "subentity")
data class SubentityTest(
@Id @GeneratedValue @Column(name = "subentity_uuid", insertable = false, updatable = false) var subentityUUID: UUID? = null,
@Column(insertable = false, updatable = false) var name: String,
) {
constructor() : this(name = "")
}

在数据库中默认设置该值:

alter table entity alter column subentity_uuid set default 'd87ee95b-06f1-52ab-83ed-5d882ae400e6'::uuid;

GL

我们可以用 getter 来注释@Column

All@column 应该单独在 getter 中注释,而不是直接声明变量。

    @Column(name = "string_value")
public String getStringValue(){
return (this.stringValue == null) ? "Default" : stringValue;
}

我试过了,当我这么做的时候

@Column(name = "is_sale", columnDefinition = "default false")
private boolean isSale = false;

enter image description here

他没有加,当我加的时候

@Column(name = "is_sale", columnDefinition = "bool default false")
private boolean isSale = false;

在本例中,Hibernate 生成了这样的 sql

alter table if exists customer_product add column is_sale bool default false

enter image description here 它帮助了我