仅在JPA TupleQuery中获取Id

时间:2014-02-25 14:28:15

标签: jpa eclipselink

不可能只从外来对象中获取id。

简单示例:

class Person {
   int id;
   String name;
   @JoinColumn(name = "ADDRESS_ID", referencedColumnName = "ID")
   @ManyToOne(fetch = FetchType.LAZY)
   Address addressesId
}

class Address {
  int id;
  String city;
}

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Tuple> q = criteriaBuilder.createTupleQuery();
Root<Person> from = q.from(Person.class);
q.multiselect(from.get(Person_.name),
              from.get(Person_.AdresseId);
TypedQuery<Tuple> query = em.createQuery(q);
List<Tuple> resultList = query.getResultList();

我只需要来自Address的ID,当然存在于Person表中,但是JPA会自动生成内部联接查询,并且省略具有空地址的实体。加入是不必要的。有没有办法只在这个TupleQuery中从Address获取id?

Xanas

1 个答案:

答案 0 :(得分:4)

JPA只能使用提供的映射来返回数据,并且由于Person中的地址外键是使用对象引用映射映射的,因此在查询中包含它必须在JPA中加入。获取空值的唯一方法是使用左外连接,如下面Koitoer所述。

另一种方法是为Person实体中的addressId外键创建另一个只读基本映射。

class Person {
   int id;
   String name;
   @JoinColumn(name = "ADDRESS_ID", referencedColumnName = "ID")
   @ManyToOne(fetch = FetchType.LAZY)
   Address address;
   @Column(name ="ADDRESS_ID", insertable=false, updatable=false)
   private Long addressId;
}

当你需要一个Address对象实例时,这将允许你使用'address'属性,当你只需要foriegn键值而不是一个完整的Address实体时,你可以使用'addressId':

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Tuple> q = criteriaBuilder.createTupleQuery();
Root<Person> from = q.from(Person.class);
q.multiselect(from.get(Person_.name),
              from.get(Person_.AddressId);
TypedQuery<Tuple> query = em.createQuery(q);
List<Tuple> resultList = query.getResultList();

将从Person表中返回name和addressId值,而不进行任何连接。