使用@JoinTable和SQLQuery获取连接

时间:2009-10-29 20:02:59

标签: java tsql hibernate left-join

我有一个带有属性“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查询,它返回一批记录,并使用连接表连接每条记录的历史记录。我想从查询中返回Record entites,并在结果中填充History对象。我的尝试看起来像这样:

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(...)或addJoin(...)似乎没有太大区别,只要使用addEntity添加最左边(根)实体。

1 个答案:

答案 0 :(得分:1)

我认为您确实需要在latestHistory中为select指定完整路径,例如

select {r.*}, {r.latestHistory.*}

否则Hibernate会感到困惑,并试图将其视为一个单独的实体。另一个选项是select中只注明should work for a single "to-one" relationship中的注入别名,只要表中的列顺序与实体中的属性顺序匹配即可。

我从来没有在关联表上的@OneToOne上试过这个。