Hibernate使用createAlias与clause生成了错误的查询

4
我有以下的表格: A: id B: id, text AB: aID, bID
我想要联结A和B,其中B.text包含单词“cat”。
这是我的Hibernate查询:
Criteria c = session.createCriteria(TableA.class, "A");
c.createAlias("A.bs", "B", JoinType.INNER_JOIN, Restrictions.like("b.text", "%cat%"));
c.setProjection(Projections.property("id"));

生成的查询语句为:
Select id 
FROM A a
INNER JOIN AB ab ON a.id=ab.aID AND (b.text like ?)
INNER JOIN B b ON b.id=ab.bID AND (b.text like ?)

由于某种原因,在两个内部连接中都出现了AND (b.text like ?)。据我理解,它应该只在第二个连接中出现。

这会导致以下异常:

java.sql.SQLException: No value specified for parameter 2

我猜这是因为它只有一个参数和两个“?”的缘故。

我漏掉了什么吗?

编辑:

添加持久化类:

@Entity
@Table(name="A")
Class A {

    @Id
    @Column(name="id", length=255)
    protected String id;

    @OneToMany
    @JoinTable(name="AB", joinColumns = @JoinColumn( name="aID"), inverseJoinColumns = @JoinColumn( name="bID"))
    @LazyCollection(LazyCollectionOption.FALSE)
    protected List<B> bs;

}

@Entity
@Table(name="B")
Class B {

    @Id
    @Column(name="id", length=255)
    protected String id;

    @Column(name="text", length=255)
    protected String text;

}

请展示您的持久化类。 - v.ladynev
请查看上面的类。 - julius_am
1个回答

1

我认为你需要创建一个别名

c.createAlias("A.bs", "b", JoinType.INNER_JOIN, Restrictions.like("b.text", "%cat%"));

更新

我认为这是一个Hibernate的bug。你可以通过在where子句中使用限制条件来修复它。

 c.createAlias("A.bs", "b", JoinType.INNER_JOIN);
 c.add(Restrictions.like("b.text", "%cat%"));

或者不使用连接表,在B中通过外键进行关联。

真是我的错,我确实是这样做的。应该是A.bs而不是A.id。 - julius_am
@julius_am 你的例子中 "B" 怎么处理? - v.ladynev
这些都是我示例中的拼写错误。使用c.createAlias("A.bs", "B")一切正常,但当我添加第三个和第四个参数时,会出现异常并生成错误的查询。我担心这是一个Hibernate的bug,但我没有解决方法。 - julius_am
你的更新是一种可选方案,但我担心它不够高效,因为在这种情况下,它将对所有行执行JOIN,然后才从WHERE中剪切非相关行,而在第一个建议中,它将在执行JOIN之前进行剪切,是吗? - julius_am
@julius_am 我认为,数据库优化器会很好地完成所有工作,但是无论如何,您都可以测试两个普通的SQL查询并比较两种方法的性能。关于外键的关联呢? - v.ladynev
@julius_am 尝试使用带别名的 sqlRestriction,也许会有所帮助。 - v.ladynev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接