处理来自 JPA/DAO 实体的结果中的非 DB 映射字段
Posted
技术标签:
【中文标题】处理来自 JPA/DAO 实体的结果中的非 DB 映射字段【英文标题】:Handling non DB mapped fields in results from JPA/DAO Entity 【发布时间】:2020-04-05 19:35:38 【问题描述】:目前我们的系统上有 3 种 POJO 对象:
@Entity - DO 数据库对象(将映射对象读写到表)
@Entity - 查看对象(只读映射对象到 SELECT 语句)
模型 - 用于演示目的的非 ORM 对象
在某些情况下,我们需要在服务层中手动获取视图对象并添加/编辑几个字段并发送到演示文稿。 是否可以使用视图对象通过添加映射到虚拟列的虚拟字段('' as dummyField 在选择语句中)来做到这一点。
了解 hibernate/jpa 将尝试在事务上下文结束时刷新对象,这将在未找到表时给出错误。我们可以使用@Transactional (readonly=true) 来解决这个问题。
这样做有什么缺点吗?而不是创建一个全新的模型并用它填充视图?
【问题讨论】:
which will give error on table not found
什么?如果您从表中读取,则该表存在。此外,一旦您离开事务,任何更改都不会自动刷新回数据库。您需要手动调用update()
写回任何更改
XtremeBaumer - 你所说的对于第一组对象是正确的,对象映射到数据库表。 View 对象是映射到 SELECT 语句的 @Entity 对象,这些语句可能具有来自多个表的列和计算的列。在这种情况下,没有物理表。
那么用户不应该有可能编辑这些实体。他们应该只能查看它们
澄清我上面的帖子:“手动添加/编辑”是指服务层中的 java 代码向使用 @Entity 检索的视图对象添加附加信息。不是 UI 端的最终用户。
【参考方案1】:
通过添加映射到虚拟列的虚拟字段(作为 select 语句中的 dummyField)
您根本不需要休眠填充字段,可以不理会sql,只需使用@javax.persistence.Transient
注释非持久字段
在事务上下文结束时刷新对象
它会在它认为合适的任何时候刷新,例如在任何其他查询之前以获得一致的结果集
这将在找不到表时给出错误
奇怪。但是我想您并不想认真地使用视图模型来阅读和。所以@Transactional (readonly=true)
无论如何都是正确的选择。
这样做有什么缺点吗?而不是创建一个全新的模型
除了软件意识形态的争论,你的意思是?这种方法似乎造成了一些混乱,显然休眠特性从服务层泄漏出来。
但是,如果您在技术层面上做对了,您就可以获得您想要的行为,并节省一些来回映射开销。
【讨论】:
使用@javax.persistence.Transient 似乎是更优雅的解决方案。如果您要将这些对象缓存在 redis 或 ehcache 等二级缓存中,这会导致任何问题吗? 看不出为什么会这样。当然,责任除外。以上是关于处理来自 JPA/DAO 实体的结果中的非 DB 映射字段的主要内容,如果未能解决你的问题,请参考以下文章