There is no difference between a view and a base table for a Hibernate mapping. This is transparent at the database level, although some DBMS do not support views properly, especially with updates. Sometimes you want to use a view, but you cannot create one in the database (i.e. with a legacy schema). In this case, you can map an immutable and read-only entity to a given SQL subselect expression using @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; }
...
}
Declare the tables to synchronize this entity with, ensuring that auto-flush happens correctly and that queries against the derived entity do not return stale data. The is available both as an attribute and a nested mapping element.
这里对于Synchronize注解的说法我不是很清楚。自动冲洗有什么问题?这里的派生实体是什么?为什么我们会得到陈旧的数据?同步注释如何解决此问题。
谁能帮我理解这一点。
最佳答案
Hibernate 实体在内存中保持持久状态。对这些实体的任何更改都会自动持久保存到数据库中。但是每次更改实体的字段时,数据库都不会更新。它在 flush 时间完成:Hibernate 决定它必须使内存中的更改持久化,因此执行适当的插入、更新和删除语句,以便数据库状态与内存中状态匹配。
什么时候发生?
- 在事务提交之前
- 当您在 session 中显式调用
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 映射到哪个表,所以它不知道在执行涉及摘要实体的查询。 Synchronize 注释允许告诉 Hibernate:此实体从项目和出价表中获取数据,因此如果针对摘要实体执行查询,请确保在执行查询之前刷新对出价和项目表的更改。
关于java - Hibernate中@Synchronize有什么用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25226244/