java - 保存实体后,Hibernate 为使用 @Formula 注释的实体属性返回 null
问题描述
我有简单的课程,如下所示:
@Entity
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
Long id;
@Column(name = "title")
String title;
@Formula("(select current_date())")
Date currentDate;
@OneToMany(mappedBy = "post")
Set<PostComment> commentList = new HashSet<>();
}
并希望在服务中更新此实体:
@Service
@Transactional
public class PostService {
private final PostRepository postRepository;
public PostService(PostRepository postRepository) {
this.postRepository = postRepository;
}
@Transactional
public Post save(Post entity) {
Post post = postRepository.saveAndFlush(entity);
System.out.println("current_date: " + post.getCurrentDate());
post.getCommentList().forEach(pc -> System.out.println(pc.getReview()));
return post;
}
}
当我检查休眠日志时,它首先是实体select
的所有字段,但是当我调用时(它用 注释)返回:Post
post.getCurrentDate()
@Formula
null
Hibernate: select post0_.id as id1_0_0_, post0_.title as title2_0_0_, (select current_date()) as formula0_0_ from post post0_ where post0_.id=?
Hibernate: update post set title=? where id=?
current_date: null
Hibernate: select commentlis0_.post_id as post_id3_1_0_, commentlis0_.id as id1_1_0_, commentlis0_.id as id1_1_1_, commentlis0_.post_id as post_id3_1_1_, commentlis0_.review as review2_1_1_ from post_comments commentlis0_ where commentlis0_.post_id=?
review
为什么它返回并记录commentList
但不返回currentDate
?是休眠错误吗?
笔记
我在 github 中推送了完整的示例项目,您可以在此处查看。
解决方案
我在我的 high-performance-java-persistence GitHub 存储库上写了一个测试用例,它就像一个魅力。
实体如下所示:
@Entity(name = "Event")
@Table(name = "event")
public static class Event {
@Id
private Long id;
@Formula("(SELECT current_date)")
@Temporal(TemporalType.TIMESTAMP)
private Date createdOn;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
}
请注意,该Date
属性也使用@Temporal
注释。
现在为了模拟您的用例,我编写了以下数据访问逻辑:
Event event = new Event();
event.setId(1L);
entityManager.persist(event);
entityManager.flush();
entityManager.refresh(event);
assertNotNull(event.getCreatedOn());
请注意refresh
由于实体缓存在 上所需的调用,persist
我们想从数据库中重新获取它。
而且,当执行它时,Hibernate 会生成以下语句:
Query:["insert into event (id) values (?)"], Params:[(1)]
Query:["select formulacur0_.id as id1_0_0_, (SELECT current_date) as formula0_0_ from event formulacur0_ where formulacur0_.id=?"], Params:[(1)]
并且测试用例运行得很好。只需在您的用例和我的用例之间进行比较调试,看看为什么您的用例不起作用而我的用例起作用。
推荐阅读
- xamarin - 为什么 CrossCurrentActivity.Current.Activity 总是为 Xamarin.Forms 中的任何其他页面提供 MainActivity?
- java - 是什么将“接口名称”与“类名称”区分开来?
- python - Scipy 最小化错误:“numpy.float64”对象不可调用
- batch-file - 如何使用需要运行脚本文件的 plink 命令运行批处理文件
- java - 如何在 Java 中调整数组的大小?
- ios - Firebase - 自定义事件 - 仅提供过去 30 分钟的事件数据
- c# - 物理键盘事件挂钩不适用于 Xamarin iOS 表单中的 Master-Detail 应用程序
- sql - Microsoft SQL Server 卡在“Install_SQLSupport_CPU64_Action”
- android - Android Picasso 无法获取图像但占位符
- regex - 正则表达式将多个字母作为一个匹配项,导致我的代码出现问题