我创建了这个简单的域,以便理解为什么以下查询不起作用。
@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());
}
有以下异常(exception):
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
才能进行查询有用吗?
谢谢!
最佳答案
因为 Owner
类是关系的实际所有者
因此反向表的主键在内部可用
所有者表作为外键。
因此,如果您从所有者表 (owner.reverse) 引用反向,您可以使用 Owner 表中可用的映射反向 ID 获取它。
但反向映射是 - 反向表在其表中没有所有者表的 id 因此,如果您尝试说 reverse.owner,它无法从其表中获取它。
所以你必须使用 reverse.owner.id 从对面的表中获取 id。
关于java - JPA:反向映射字段上的查询子句 - 未设置参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23356480/