标准查询多对多

时间:2012-11-25 15:10:41

标签: hibernate

我已经创建了下面提到的SQL的HQL,但我无法通过Criteria和Sub查询执行它。请帮我通过Criteria执行以下查询(SQL& HQL)。谢谢提前 ...

SQL:

SELECT * FROM app_interface ain WHERE ain.id IN (SELECT ai.id FROM app_interface ai INNER JOIN app_module_interface ami ON ami.interface_id = ai.id INNER JOIN app_module am ON am.id = ami.module_id WHERE am.id = :id

HQL:

FROM AppModule oam WHERE oam.id IN(SELECT am.id FROM AppModule am INNER JOIN am.appRoles ar WHERE ar.id = :id)

通过标准需要...... .. ?????

情景:

public class AppModule implements java.io.Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", unique = true, nullable = false)
private Integer id;

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "appModules")  
private Set<AppRole> appRoles = new HashSet<AppRole>(0);

}

公共类AppRole实现了java.io.Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", unique = true, nullable = false)
private Integer id;

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@OrderBy("name")
@JoinTable(name = "app_role_module", joinColumns = {
@JoinColumn(name = "role_id", nullable = false, updatable = false)}, inverseJoinColumns = {
    @JoinColumn(name = "module_id", nullable = false, updatable = false)})
private Set<AppModule> appModules = new HashSet<AppModule>(0);

}

1 个答案:

答案 0 :(得分:2)

嗯,首先,您的查询过于复杂。它可以改写为

select distinct am from AppModule am 
inner join am.appRoles ar 
WHERE ar.id = :id

我不知道你为什么要使用标准而不是这个简单易读的HQL查询,但是如果你真的想要,那么使用

Criteria c = session.createCriteria(AppModule.class, "am");
c.createAlias("am.appRoles", "ar");
c.add(Restrictions.eq("ar.id", theRoleId));
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

编辑:

如果要实施查询

from AppModule oam WHERE oam.id not in (
    select am.id from AppModule am inner am.appRoles ar where ar.id = :id)

,然后您可以使用以下代码:

DetachedCriteria dc = DetachedCriteria.forClass(AppModule.class, "am");
dc.createAlias("am.appRoles", "ar");
dc.add(Restrictions.eq("ar.id", theRoleId));
dc.setProjection(Projections.id());

Criteria c = session.createCriteria(AppModule.class, "oam");
c.add(SubQueries.propertyNotIn("oam.id", dc));