涉及多个关联的HQL JOIN

时间:2012-12-16 14:52:49

标签: java hibernate

我有三个关系UserDetails hasmany FiledTaskTask hasMany FiledTask的实体。我想要的只是特定FiledTask

User列表

对于UserDetails:

@OneToMany(mappedBy="user",cascade=CascadeType.ALL)
Collection<FiledTask> filedTasks = new ArrayList<FiledTask>();

对于我有的任务

@OneToMany(mappedBy="task")
Collection<FiledTask> filedTasks = new ArrayList<FiledTask>();

FiledTask看起来像

@ManyToOne
@JoinColumn(nullable = false, name = "taskId")
private Tasks task;
@ManyToOne
@JoinColumn(nullable = false, name = "userId")
private UserDetails user;

我试过了

query = session.createQuery("from Tasks as tasks inner join tasks.filedTasks as files with files.user = :user");
query.setParameter("user", user); //user is UserDetails instance

但是我得到的错误子句只能引用驱动表中的列,意味着FiledTask不能用userId进行比较吗?

with clause can only reference columns in the driving table [from com.akhi.app.cdm.Tasks as tasks inner join tasks.filedTasks as files with files.user = :user]

3 个答案:

答案 0 :(得分:5)

如果您想要给定用户的FiledTasks,那么最简单的事情就是

UserDetails user = session.find(UserDetails.class, userId);
Collection<FiledTask> filesTasks = user.getFiledTasks();

使用HQL,它将是

select f from FiledTask f where f.user = :user

如果你想要的实际上是给定用户的任务,那么查询就是

select t from Tasks t
inner join t.filedTasks filedTask
where filedTask.user = :user

请注意,实体Tasks应命名为Task。实例表示单个任务,而不是多个任务。

答案 1 :(得分:5)

好的,看起来Hibernate中有一个错误

https://hibernate.atlassian.net/browse/HHH-2772

我认为在你的情况下你需要做的是

query = session.createQuery("from Tasks as tasks inner join tasks.filedTasks as files with files.user.id = :userId");
query.setParameter("userId", user.id); 

希望这有助于某人。我花了几个小时来做​​这件事。

答案 2 :(得分:0)

我使用MySql(Inno)DB加上我从Hibernate的MySQL5InnoDBDialect - 派生的方言类时遇到了同样的问题。

我必须覆盖supportsRowValueConstructorSyntax-method并让它返回false,因为MySQLDialect(它是MySQL5InnoDBDialect的基类)返回true

@Override
public boolean supportsRowValueConstructorSyntax() {
    return false;
}

这样做,hibernate不会使用对象引用(在你的情况下为.user)来创建一个用于比较的元组。我希望,这会有所帮助。