JPA - 保存后自动生成的字段为空

时间:2017-11-30 07:58:29

标签: spring hibernate spring-mvc jpa spring-boot

我有一个Account实体,我正在尝试使用save函数来保留它。我的代码:

@Override
public Account createAccount(String pin) {

    Account account = new Account();
    account.setBalance(0L);
    account.setPin(pin);

    return accountRepository.save(account);

}

现在我的实体类有一个名为accountNumber的自动生成字段。我的实体类:

@Entity
@Table(name = "accounts")
@Data
public class Account {

    @Column(name = "account_number", length = 32, insertable = false)
    private String accountNumber;

    private Long balance;


}

现在在调用save之后,返回的实体的accountNumbernull,但我可以在intellij数据库视图中看到它实际上不是null。所有其他自动生成的字段(如id等)都在返回的实体中,只有accountNumber为空。 accountNumber的默认值在sql文件中设置:

ALTER TABLE accounts
  ALTER COLUMN account_number SET DEFAULT DefaultValueSerializer(TRUE, TRUE, 12);

此处,DefaultValueSerializer是生成帐号的功能。

我尝试了其他可用的解决方案,例如使用saveAndFlush()等,在我的情况下没有任何效果。可能是什么问题?

3 个答案:

答案 0 :(得分:1)

正如评论中所提到的,Hibernate不知道数据库引擎级别会发生什么,因此它看不到生成的值。

明智的做法是将帐号生成转换为JPA级别,而不是使用db defaults。

我建议您学习注释@GeneratedValue和相关内容,例如@SequenceGenerator。这样生成账号的控制在JPA级别,保存后不需要刷新实体等东西。

一个起点:Java - JPA - Generators - @SequenceGenerator

对于非id字段,可以在注释为@PrePersist的方法中生成值,如其他答案所示,但您可以在Account构造函数中进行初始化。

另请参阅this answer了解选项。

答案 1 :(得分:1)

您可以在将字段设置为默认值的实体内创建带注释的@PrePersist方法。

这样jpa就会知道默认值。

对于不同的实体生命周期事件https://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/listeners.html

,还有其他此类注释可用

P.S。如果你决定这样做,请记得删除insertable = false

答案 2 :(得分:0)

使用

/usr/local/bin/wkhtmltoimage-amd64 --transparent --height 300 --width 210 temporary.html image.png 

为您的ID。并将保存保留为@Id @GeneratedValue(strategy = GenerationType.IDENTITY) ,以便您可以立即看到更改,如果有的话。我还建议将ID和帐号分开。它们不应该是一样的。尝试调试程序并查看值停止传递的位置。