Joh*_*n D 5 hibernate jpa spring-boot
我正在使用带有 JPA/Hibernate 的 SpringBoot,我想添加审计。
我创建了一个具有以下内容的抽象实体:
@CreatedDate
@NotNull
@Column(columnDefinition = "DATETIME(3)", updatable = false)
private ZonedDateTime createdDate;
@LastModifiedDate
@Column(columnDefinition = "DATETIME(3)")
private ZonedDateTime lastModifiedDate;
Run Code Online (Sandbox Code Playgroud)
应用程序
我正在开发一个带有简单 CRUD 实体的 RESTful API。我的资源(控制器)在 jpa 存储库上使用 save() 方法进行创建和更新
问题 :
当我在实体上调用 repository.save() 来更新它时,“createdDate”被忽略(这是正常的),但该方法返回的实体将其“createdDate”设置为 null。
然后实体被放入缓存中,下一个 get 也将其 createdDate 值设为 null。
如何在不允许修改字段 createdDate 和使用 JpaCrudRepository 的情况下更新实体?
更新
存储库定义:
public interface ModelRepository extends JpaRepository<Model, Long> {
Run Code Online (Sandbox Code Playgroud)
休息控制器:
public ResponseEntity<Model> createModel(@RequestBody Model model) throws URISyntaxException {
Model result = modelRepository.save(model);
return ResponseEntity.created(new URI("/api/v1/models/" + result.getId()))
.body(result);
}
Run Code Online (Sandbox Code Playgroud)
端点返回的 Json 包含“createdDate: null”
更新 2
为了解决这个问题,我创建了一个这样的服务:
@Override
public Model save(Model model) {
Model result = modelRepository.save(model);
return result;
}
@Override
public Model update(Long id, Model model) {
Model existingModel = modelRepository.findOne(id);
if (existingModel == null) {
return null;
}
// Non updatable fields
model.setId(id);
model.setCreatedDate(existingModel.getCreatedDate());
Model result = modelRepository.save(model);
return result;
}
Run Code Online (Sandbox Code Playgroud)
为了完成这项工作,我还从 createdDate 字段中删除了“updatable = false”,以防止结果在保存后出现空日期。
如果我们之后必须手动处理它,我不明白使用“可更新=假”的目的。
如果我们暂时考虑一下普通的 Hibernate,那么updatable=false在映射上指定是完全合法的,但显然必须在某个地方初始化该值,以便 Hibernate 知道在插入时要在列中放置什么值。
您自己设置值的解决方案正是普通 Hibernate 用户必须做的。
但我注意到你的模型使用了一个@CreatedDate注释,从我简短的谷歌搜索来看,它似乎是 Spring Data 公开的东西,与 Hibernate 无关。对我来说,这意味着这里可能没有正确配置某些内容。
我从未使用过 Spring 数据中的这个,但你可以在这里找到另一篇文章。也许它可以帮助突出显示您的配置可能在哪里关闭以及为什么@CreatedDate注释没有按您的预期初始化该字段。
更新
在外部源向您提供需要在现有实体之上应用的状态(例如您的update方法的情况)的情况下,您首先需要检索该实体并相应地覆盖您的输入。
// Some controller or business method
public Object updateModel(Model input) {
final Model model = modelRepository.findOne( input.getId() );
if ( model != null ) {
// replicate business case fields
// sometimes this can be done using frameworks like ObjectMapper, etc.
// this is just a simple case.
model.setField1( input.getField1() );
model.setField2( input.getField2() );
return modelRepository.update( model );
}
throw new UnknownObjectException( "No Model found with id: " + input.getId() );
}
Run Code Online (Sandbox Code Playgroud)
希望有帮助。
| 归档时间: |
|
| 查看次数: |
10731 次 |
| 最近记录: |