JPA CriteriaApi:与实体关系不存在

时间:2014-06-07 07:53:57

标签: java sql hibernate jpa

我想使用标准api不存在。检查是当汽车不存在时,返回所有租赁。问题是即使我删除了subQueryPredicates也没有效果,使用Rental表中的Car字段的表之间的连接不起作用。请帮帮我。

CriteriaBuilder cb = em.getCriteriaBuilder();  
CriteriaQuery<Car> query = cb.createQuery(Car.class); 
Root<Car> tbCar =  query.from(Car.class); 
query.select(tbCar);

Subquery<Rental> subquery = query.subquery(Rental.class); 
Root<Rental> tbRental = subquery.from(Rental.class);  
subquery.select(tbRental);

List<Predicate> subQueryPredicates = new ArrayList<Predicate>(); 
subQueryPredicates.add(cb.equal(tbRental.get("car"), tbCar));
subQueryPredicates.add(cb.greaterThan(tbRental.<LocalDate>get("from"), counterDate));
subQueryPredicates.add(cb.lessThan(tbRental.<LocalDate>get("to"), counterDate));
subQueryPredicates.add(cb.equal(tbRental.get("status"), "booked"));
subquery.where(subQueryPredicates.toArray(new Predicate[]{}));

List<Predicate> mainQueryPredicates = new ArrayList<Predicate>(); 
mainQueryPredicates.add(cb.not(cb.exists(subquery))); 

这是我的租赁实体。 Rental和Car之间的联系是“汽车”字段。

@Entity
public class Rental {
public static final String STATUS_BOOKED = "booked";
public static final String STATUS_CANCELED = "canceled";

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

@NotBlank
private String status;

@NotNull
@ManyToOne
private Car car;

@NotNull
@ManyToOne
private Client client;

@NotNull
@Column(name="\"from\"")
private LocalDate from;

@NotNull
@Column(name="\"to\"")
    private LocalDate to;

这是我的汽车实体

@Entity
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@ManyToOne
private Provider provider;

@NotBlank
@Column(unique = true)
private String licensePlate;

这是我想模仿的HQL:

String sql = "from Car c where not exists (" 
+ "from Rental r" 
+ "where " 
+ "r.car = c "    
+ "and "  
+ counterDate.toString()
+ "between r.from and r.to " 
+ "and r.status ='booked' )";

2 个答案:

答案 0 :(得分:0)

在JPA 2.0中查看SubQueries上的这个Question。在我看来你错过了Path,它将主查询映射到子查询?

答案 1 :(得分:0)

我猜你的标准末尾缺少where条款:

...

List<Predicate> mainQueryPredicates = new ArrayList<Predicate>(); 
mainQueryPredicates.add(cb.not(cb.exists(subquery))); 
query.where(mainQueryPredicates.toArray(new Predicate[]{}));

因此不考虑子查询。