@Entity
@Table(name = "tb_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private Boolean deleteFlag;
private Boolean activeFlag;
public User() {
}
}
如上实体类代码,两个布尔值的数据库字段是设置了默认值 0 的,在新增保存时,如果没设置两个属性的值,插入后并不能得到数据库的默认值,即仍然是 null 。
目前想到的办法有两个:
在实体属性上面加注解:@Generated(GenerationTime.INSERT)
加这个注解后,JPA 在插入数据库后,会执行一次 select 查询把相关字段的值查询回来,然后赋值给对象。
在实体属性上加上默认值,如 private Boolean deleteFlag = false
这种方法在阿里手册里不推荐,然而手册上面举的反例是时间字段,思考好久感觉并没有什么不妥的地方?
综上,不知道有没有更好的解决方案?
1
Oktfolio 2021-01-07 12:10:09 +08:00
|
2
wangyanrui 2021-01-07 12:14:24 +08:00 via Android
为什么要相信阿里手册😂
|
3
Oktfolio 2021-01-07 12:18:54 +08:00
@wangyanrui 实际确实不应该这么做。
|
5
wangyanrui 2021-01-07 12:25:19 +08:00 via Android
@Oktfolio 😂为什么不应该这么做
|
6
967182 2021-01-07 12:54:34 +08:00
boolean
|
7
Oktfolio 2021-01-07 13:59:50 +08:00
@NULL2020 可以啊,怎么不行?我只给一个字段赋了值,Hibernate SQL 执行日志是 insert into table_name (field) values (?)。
|
8
zoharSoul 2021-01-07 14:06:34 +08:00
@wangyanrui 因为很奇怪
|
9
Oktfolio 2021-01-07 14:06:54 +08:00
@wangyanrui 如果只是逻辑删除字段默认给 false 的话,问题不大。但是如果是别的字段,你又使用 DO 去做查询的话就会有坑,特别是时间,除非你再赋值为 null 。
|
12
Oktfolio 2021-01-07 14:23:40 +08:00
@NULL2020 entityManager.clear(); 再根据 save 返回的 id 查询出来。但是你也得加上这个注解插入到数据库的才不会为 null 。
|
14
wangyanrui 2021-01-07 15:24:54 +08:00 via Android
|
15
ccccccccw 2021-01-07 15:38:56 +08:00
@wangyanrui new 一个空的对象作为查询条件的时候,本来 Boolean 的默认值是 null,jpa 就不会把他作为条件添加到 sql 中,但是如果设置了 false,jpa 就会将 false 添加到查询条件中
|
16
ccccccccw 2021-01-07 15:39:55 +08:00
@wangyanrui 也就是说,where deleteFlag = false
|
17
aragakiyuii 2021-01-07 15:42:06 +08:00 via iPhone
@wangyanrui 如果用 Example 这种方式去查那得注意一下,不处理的话会默认当成查询条件
|
18
aragakiyuii 2021-01-07 15:43:52 +08:00 via iPhone
这种我习惯把字段=默认值语句写在有参构造函数里
|
19
ApmI00 2021-01-07 16:14:12 +08:00
所以,与其等插入后再查回,影响性能,不如在保存对象前,手动设置这两个字段,这样也不违反手册,就是代码啰嗦了一点。。。至于时间字段,怕是得用 @DynamicUpdate 配合建表 sql 了吧!!!不知道理解的可对
|
20
DeepUse 2021-01-07 16:21:50 +08:00
@Data
@ToString @MappedSuperclass @EqualsAndHashCode public class BaseEntity { @Column(name = "create_time") @Temporal(TemporalType.TIMESTAMP) private Date createTime; @Column(name = "update_time") @Temporal(TemporalType.TIMESTAMP) private Date updateTime; @PrePersist protected void prePersist() { Date now = DateUtils.now(); if (createTime == null) { createTime = now; } if (updateTime == null) { updateTime = now; } } @PreUpdate protected void preUpdate() { updateTime = new Date(); } @PreRemove protected void preRemove() { updateTime = new Date(); } } |
21
xuanbg 2021-01-07 16:34:06 +08:00
我一般在 get 方法里面这样写。但得注意需要正常返回 null 的字段可别也这样干。
pubic Boolean getDeleteFlag(){ return deleteFlag == null ? false : deleteFlag; } |
22
472690980 2021-01-07 16:41:05 +08:00
@Column(columnDefinition = "Integer default 0")
private Integer accessFailedCount; 可以设置字段默认值,或者你直接用小写的 bool 不就完事了 默认就是 false |
23
NULL2020 OP |
24
wangyanrui 2021-01-07 18:34:16 +08:00 via Android
|
25
wangyanrui 2021-01-07 18:36:38 +08:00
|
26
472690980 2021-01-08 08:30:46 +08:00
小写的 bool 不就完事了吗,说明你这个字段是不可空的
|
27
zhenjiachen 2021-01-08 13:40:41 +08:00
阿里不推荐属性默认值?那 kotlin 的 data class 全是默认值,那是 kotlin 错了?
|