条件生成器分组依据和计数不起作用
Criteria builder group by and having count does not work
这是我要实现的查询:
SELECT *
FROM ROOMENTITY R
JOIN CALENDARENTITY C ON R.id = C.room_id
WHERE C.available = TRUE AND
C.date BETWEEN :checkin AND
:checkout
GROUP BY C.room_id
HAVING COUNT(C.room_id)>= diffdays
这是我的代码:
manager = factory.createEntityManager();
boolean hasPredicates = false;
final CriteriaBuilder criteriaBuilder = manager.getCriteriaBuilder();
final CriteriaQuery<RoomEntity> q = criteriaBuilder.createQuery(RoomEntity.class);
List<Predicate> predicates = new ArrayList<Predicate>();
Root<RoomEntity> fromRooms = q.from(RoomEntity.class);
String checkinDate = filter.getCheckinDate();
String checkoutDate = filter.getCheckoutDate();
if (checkinDate != null || checkoutDate != null) {
hasPredicates = true;
java.sql.Date checkin = java.sql.Date.valueOf(filter.getCheckinDate());
java.sql.Date checkout = ava.sql.Date.valueOf(filter.getCheckoutDate());
int diffInDays = (int)( (checkout.getTime() - checkin.getTime()) / (1000 * 60 * 60 * 24) ) + 1;
System.out.println("Days: " + diffInDays);
Join<RoomEntity, CalendarEntity> calendarEntityJoin= fromRooms.join("calendarEntities", JoinType.INNER);
calendarEntityJoin.on(
criteriaBuilder.equal(calendarEntityJoin.join("calendarId").<Integer>get("room_id"), fromRooms.<Integer>get("id"))
);
predicates.add(criteriaBuilder.and(
criteriaBuilder.equal(calendarEntityJoin.<String>get("available"), true),
criteriaBuilder.between(calendarEntityJoin.join("calendarId").<Date>get("date"),
checkin, checkout)
));
q.groupBy(calendarEntityJoin);
q.having(criteriaBuilder.gt(criteriaBuilder.count(fromRooms), diffInDays));
}
我的房间实体:
public class RoomEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", nullable = false, unique = true)
private Integer id;
@OneToMany(mappedBy = "roomEntity", cascade = CascadeType.ALL)
private Collection<CalendarEntity> calendarEntities;
}
我的日历实体:
public class CalendarEntity {
@EmbeddedId
private CalendarId calendarId;
@Basic
@Column(name = "available", nullable = false)
private Boolean available;
@ManyToOne
@JoinColumn(name = "room_id", referencedColumnName = "id", insertable = false, updatable = false)
private RoomEntity roomEntity;
}
我的 CalendarEntity 嵌入 ID:
@Embeddable
public class CalendarId implements Serializable {
@Column(name= "date", nullable = false)
private Date date;
@Column(name = "room_id", nullable = false)
private Integer room_id;
}
在 group by 和 count 之前一切都很好。当我 运行 这个和我用下面的代码打印查询时,然后有 groupby/having:
if (hasPredicates)
q.where(criteriaBuilder.and(predicates.toArray(new Predicate[0])));
final TypedQuery<RoomEntity> TQ = manager.createQuery(q);
TQ.setFirstResult(filter.getStart());
TQ.setMaxResults(filter.getSize());
System.out.println("\n\nQuery:\n" + +Q.unwrap(JpaQuery.class).getDatabaseQuery().getSQLString() + "\n\n\n");
最后的查询不是我想要的,它确实实现了 group by 和 having count。
更新:
这是我现在收到的查询:
SELECT t1.id, t1.bathrooms, t1.bedrooms, t1.beds, t1.description, t1.exta_person_price, t1.house_rules, t1.max_people, t1.min_overnights, t1.neightborhood, t1.overnight_price, t1.square_meters, t1.title, t1.transport, t1.room_host, t1.room_location, t1.room_type_id FROM CALENDARENTITY t0, ROOMENTITY t1 WHERE (((t0.available = ?) AND (t0.date BETWEEN ? AND ?)) AND ((t0.room_id = t1.id) AND (t0.room_id = t1.id))) ORDER BY t1.overnight_price ASC
缺少分组,有计数!
在我使用多选后查询有效。
Q.multiselect(fromRooms);
这是我要实现的查询:
SELECT *
FROM ROOMENTITY R
JOIN CALENDARENTITY C ON R.id = C.room_id
WHERE C.available = TRUE AND
C.date BETWEEN :checkin AND
:checkout
GROUP BY C.room_id
HAVING COUNT(C.room_id)>= diffdays
这是我的代码:
manager = factory.createEntityManager();
boolean hasPredicates = false;
final CriteriaBuilder criteriaBuilder = manager.getCriteriaBuilder();
final CriteriaQuery<RoomEntity> q = criteriaBuilder.createQuery(RoomEntity.class);
List<Predicate> predicates = new ArrayList<Predicate>();
Root<RoomEntity> fromRooms = q.from(RoomEntity.class);
String checkinDate = filter.getCheckinDate();
String checkoutDate = filter.getCheckoutDate();
if (checkinDate != null || checkoutDate != null) {
hasPredicates = true;
java.sql.Date checkin = java.sql.Date.valueOf(filter.getCheckinDate());
java.sql.Date checkout = ava.sql.Date.valueOf(filter.getCheckoutDate());
int diffInDays = (int)( (checkout.getTime() - checkin.getTime()) / (1000 * 60 * 60 * 24) ) + 1;
System.out.println("Days: " + diffInDays);
Join<RoomEntity, CalendarEntity> calendarEntityJoin= fromRooms.join("calendarEntities", JoinType.INNER);
calendarEntityJoin.on(
criteriaBuilder.equal(calendarEntityJoin.join("calendarId").<Integer>get("room_id"), fromRooms.<Integer>get("id"))
);
predicates.add(criteriaBuilder.and(
criteriaBuilder.equal(calendarEntityJoin.<String>get("available"), true),
criteriaBuilder.between(calendarEntityJoin.join("calendarId").<Date>get("date"),
checkin, checkout)
));
q.groupBy(calendarEntityJoin);
q.having(criteriaBuilder.gt(criteriaBuilder.count(fromRooms), diffInDays));
}
我的房间实体:
public class RoomEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", nullable = false, unique = true)
private Integer id;
@OneToMany(mappedBy = "roomEntity", cascade = CascadeType.ALL)
private Collection<CalendarEntity> calendarEntities;
}
我的日历实体:
public class CalendarEntity {
@EmbeddedId
private CalendarId calendarId;
@Basic
@Column(name = "available", nullable = false)
private Boolean available;
@ManyToOne
@JoinColumn(name = "room_id", referencedColumnName = "id", insertable = false, updatable = false)
private RoomEntity roomEntity;
}
我的 CalendarEntity 嵌入 ID:
@Embeddable
public class CalendarId implements Serializable {
@Column(name= "date", nullable = false)
private Date date;
@Column(name = "room_id", nullable = false)
private Integer room_id;
}
在 group by 和 count 之前一切都很好。当我 运行 这个和我用下面的代码打印查询时,然后有 groupby/having:
if (hasPredicates)
q.where(criteriaBuilder.and(predicates.toArray(new Predicate[0])));
final TypedQuery<RoomEntity> TQ = manager.createQuery(q);
TQ.setFirstResult(filter.getStart());
TQ.setMaxResults(filter.getSize());
System.out.println("\n\nQuery:\n" + +Q.unwrap(JpaQuery.class).getDatabaseQuery().getSQLString() + "\n\n\n");
最后的查询不是我想要的,它确实实现了 group by 和 having count。
更新: 这是我现在收到的查询:
SELECT t1.id, t1.bathrooms, t1.bedrooms, t1.beds, t1.description, t1.exta_person_price, t1.house_rules, t1.max_people, t1.min_overnights, t1.neightborhood, t1.overnight_price, t1.square_meters, t1.title, t1.transport, t1.room_host, t1.room_location, t1.room_type_id FROM CALENDARENTITY t0, ROOMENTITY t1 WHERE (((t0.available = ?) AND (t0.date BETWEEN ? AND ?)) AND ((t0.room_id = t1.id) AND (t0.room_id = t1.id))) ORDER BY t1.overnight_price ASC
缺少分组,有计数!
在我使用多选后查询有效。
Q.multiselect(fromRooms);