【发布时间】:2018-05-14 02:08:47
【问题描述】:
我有一个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 后,返回的实体有accountNumber 和null,但我可以在intellij 数据库视图中看到它实际上不为空。所有其他自动生成的字段(如 id 等)都存在于返回的实体中,只是 accountNumber 为空。 accountNumber 的默认值在 sql 文件中设置:
ALTER TABLE accounts
ALTER COLUMN account_number SET DEFAULT DefaultValueSerializer(TRUE, TRUE, 12);
这里,DefaultValueSerializer 是生成帐号的函数。
我已经尝试过其他可用的解决方案,例如使用 saveAndFlush() 等,但在我的情况下没有任何效果。可能是什么问题?
【问题讨论】:
-
因为 hibernate 不是这样工作的,所以它对在您的数据库中自动生成列一无所知,并且不会像这样自动更新值。您需要从数据库中重新检索
Account以获取该字段。 -
@M.Deinum 也试过了。保存后,我使用
findOne函数检索帐户。令人惊讶的是,返回的accountNumber仍然是null。由于某种原因,findOne不会导致选择查询,因为我看不到任何由于findOne函数调用而记录的休眠查询。 -
因为,正如您所注意到的,它不会从数据库中检索它。使用 ORM 工具,如果具有请求 id 的所需实体已存在于缓存中,则该工具将首先检查一级缓存,并且您可以获得该实例。您首先必须清除缓存 (
entitymanager.clear()) 并重新加载它或refresh(entityManager.refresh) 实体。 -
你确实是对的。我最终为
accountNumber字段使用了@Generated(value = INSERT)注释。它让 JPA 知道该值是在插入期间生成的,因此它将在保存后再次从数据库中查询该值以获取更新的值。感谢您为我指明正确的方向。 -
注解
@Generated似乎是hibernate特定的所以不是JPA。
标签: spring hibernate spring-mvc jpa spring-boot