JPA:反向映射字段的查询子句 - 未设置参数

时间:2014-04-29 05:48:03

标签: java spring hibernate jpa

我已经制作了这个简单的域名,以便了解以下查询为什么不起作用。

@Entity
public class Owner {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(cascade = CascadeType.ALL)
    private Reverse reverse;

    //getters / setters
}

@Entity
public class Reverse {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(mappedBy = "reverse")
    private Owner owner;

    //getters / setters
}

此测试失败:

@Test
@Transactional
public void testQueryByEntity() throws Exception {
    Reverse reverse = new Reverse();
    Owner owner = new Owner();

    owner.setReverse(reverse);
    entityManager.persist(owner);

    entityManager.flush();
    entityManager.clear();

    Reverse dbReverse =
            em.createQuery("from Reverse r where r.owner = :owner", Reverse.class)
                    .setParameter("owner", owner)
                    .getSingleResult();

    System.out.println("Revrse id: " + dbReverse.getId());
}

有以下例外:

Caused by: org.h2.jdbc.JdbcSQLException: Parameter "#2" is not set; SQL statement:
select reverse0_.id as id1_ from T_ORDER reverse0_ where reverse0_.id=? limit ? [90012-156]

所有者方面的相同查询有效:

Owner dbOwner = 
    em.createQuery("from Owner o where o.reverse = :reverse", Owner.class)
        .setParameter("reverse", reverse)
        .getSingleResult();

为了使查询工作,我需要以这种方式修改它:

Reverse dbReverse = 
    em.createQuery("from Reverse r where r.owner.id = :ownerId", Reverse.class)
        .setParameter("ownerId", owner.getId())
        .getSingleResult();

所以我的问题是:

为什么如果在where子句中我有这种反向映射条件,我需要查询r.owner.id而不是简单地r.owner才能使我的查询有效?

谢谢!

1 个答案:

答案 0 :(得分:1)

因为Owner类是实际的owner of the relationship 因此内部可以使用反向表的主键 所有者表作为外键。

所以如果你从所有者表(owner.reverse)引用反向,你可以使用所有者表中可用的映射反向id来获取它。

但是反向映射是 - 反向表在其表中没有Owner表的id 因此,如果你试图说反向。它不能从它的表中获取它。

所以你必须使用reverse.owner.id从对面的表中获取id。