我已经制作了这个简单的域名,以便了解以下查询为什么不起作用。
@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
才能使我的查询有效?
谢谢!
答案 0 :(得分:1)
因为Owner
类是实际的owner of the relationship
因此内部可以使用反向表的主键
所有者表作为外键。
所以如果你从所有者表(owner.reverse)引用反向,你可以使用所有者表中可用的映射反向id来获取它。
但是反向映射是 - 反向表在其表中没有Owner表的id 因此,如果你试图说反向。它不能从它的表中获取它。
所以你必须使用reverse.owner.id从对面的表中获取id。