我有一个具有属性“ latestHistory”的映射实体,该属性通过连接表进行映射,例如:
class Record {
@OneToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, fetch = FetchType.LAZY, optional = true)
@JoinTable(name = "latest_history_join_view", joinColumns = { @JoinColumn(name = "record_id") }, inverseJoinColumns = { @JoinColumn(name = "history_id") })
@AccessType("field")
public History getLatestHistory() { ... }
}
当我调用myRecord.getLatestHistory()时,映射工作正常。
我有一个复杂的本机SQL查询,该查询返回一批记录,并使用连接表对每个记录的历史记录进行连接。我想从查询中返回记录实体,并在结果中填充历史记录对象。我的尝试如下所示:
StringBuffer sb = new StringBuffer();
sb.append("select {r.*}, {latestHistory.*}");
sb.append(" from record r");
sb.append(" left join latest_history_join_view lh on lh.record_id = r.record_id");
sb.append(" left join history latestHistory on latestHistory.history_id = lh.history_id");
SQLQuery query = session.createSQLQuery(sb.toString());
query.addEntity("r", Record.class).addJoin("latestHistory", "r.latestHistory");
当我这样做时,它会生成一个查询,例如:
select
r.record_id, r.name...,
r_1.history_id, --this part is wrong; there is no such alias r_1
latestHistory.history_id, latestHistory.update_date, ...
from record r
left join latest_history_join_view lh on lh.record_id = r.record_id
left join history latestHistory on latestHistory.history_id = lh.history_id
如何在不弄乱选择列表的情况下使其正确加入并获取我的关联?
[更新:我尝试过的一些方法:
select {r.*}, {latestHistory.*} -> SQL error, generates a wrong column name "r_1.history_id"
select {r.*}, {anyOtherEntityAssociatedToR.*} -> wrong column name (as above)
select {r.*}, {r.history_id}, {latestHistory.*} -> hibernate error, r has no history_id column
select r.*, lh.history_id as history_id -> this works (though hackish), but doesn't accomplish the join
select r.*, lh.history_id as history_id, latestHistory.* -> appears correct, but results in column name collisions
select r.*, {latestHistory.*} -> error when hibernate looks for a nonexistent column in the result set (this happens if there is any alias at all in the select list)
只要使用addEntity添加最左边的(根)实体,我使用addEntity(...)还是addJoin(...)似乎并没有太大的区别。
]
最佳答案
我认为您实际上需要在latestHistory
中为select
指定完整路径。
select {r.*}, {r.latestHistory.*}
否则,Hibernate会感到困惑,并尝试将其视为独立的实体。另一个选择是,只要表中的列顺序与实体中的属性顺序匹配,就不要在所有should work for a single "to-one" relationship中都在
select
中指定注入的别名。但是,我从未在@OneToOne关联表上尝试过此操作。