Hibernate的视图和基表之间没有区别 映射。这在数据库级别是透明的,尽管有些DBMS 不正确支持视图,尤其是更新时。有时你 想要使用视图,但不能在数据库中创建一个视图(即 使用遗留架构)。在这种情况下,您可以映射一个不可变的和 使用的给定SQL子选择表达式的只读实体 @ org.hibernate.annotations.Subselect:
@Entity
@Subselect("select item.name, max(bid.amount), count(*) "
+ "from item "
+ "join bid on bid.item_id = item.id "
+ "group by item.name")
@Synchronize( {"item", "bid"} ) //tables impacted
public class Summary {
@Id
public String getId() { return id; }
...
}
声明表以同步此实体,确保这样做 自动刷新正确发生,并查询派生的 实体不返回陈旧数据。它可以作为 一个属性和一个嵌套的映射元素。
我不清楚这里给出的同步注释的声明。自动刷新有什么问题?这里派生的实体是什么?为什么我们会得到过时的数据?同步注释如何解决此问题。
有人可以帮助我理解这一点。
答案 0 :(得分:17)
Hibernate实体在内存中保持持久状态。对这些实体的任何更改都会自动保持对数据库的持久性。但是每次更改实体字段时都不会更新数据库。它是在 flush 时完成的:Hibernate决定它必须使内存中的更改持久化,从而执行适当的insert,update和delete语句,以便数据库状态与in匹配 - 记忆状态。
什么时候发生?
flush()
时让我们关注第三项。假设您有一个Order实体,映射到订单表。假设您已按ID加载订单并修改其金额。修改仅在内存中。现在执行以下查询:
select sum(o.amount) from Order o
显然,此查询的结果取决于修改后的实体的新数量。在执行查询之前,Hibernate会检测到这一点并刷新对Order实体的更改,以确保查询返回正确的结果。如果查询已经
select c from Customer c where c.name = 'John'
在执行查询之前,Hibernate不会刷新对Order实体的更改,因为它的结果并不依赖于订单金额的新值:订单表不参与此查询。
现在问你的问题:既然Hibernate没有@Table
注释来知道摘要映射到哪个表,那么在它之前它不应该知道它应该自动刷新的时间。执行涉及Summary实体的查询。同步注释允许告知Hibernate:此实体从项目和投标表中获取数据,因此如果对Summary实体执行查询,请确保在执行查询之前刷新对bid和items表的更改。