2017-07-20 82 views
6

To zapytanie chcę osiągnąć:Kryteria Budowniczy Grupa autorstwa i mający licznik nie działa

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 

To jest mój kod:

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)); 
} 

My Room Podmiot:

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; 
} 

Mój kalendarz: Nieaktualny:

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; 
} 

Moja CalendarEntity Wbudowany 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; 
} 

Wszystko jest dobre, aż do grupy przez i posiadające count. Gdy ten i drukować kwerendy z tego kodu poniżej, to nie jest GroupBy/posiadające:

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"); 

Kwerenda w końcu nie jest to, co chcę i to robi wdrożenia przez grupy i mający liczyć.

UPDATE: To zapytanie otrzymuję teraz:

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 

go brakuje grupy przez i posiadające count!

+0

Dodaj informacje o oczekiwanych wynikach lub błędach, które otrzymujesz. –

+0

To, czego się spodziewam, to najwyższe zapytanie, które ma zostać utworzone, ale ostatecznie to, co się tworzy, to najwyższa kwerenda z 2 ostatnimi liniami, grupowaniem i liczeniem. – peterthunder

+0

Czy sprawdziłeś, czy poprawnie utworzyłeś encje, używając odpowiednich adnotacji, nie musisz pisać tak dużo kodu. Sprawdź również zapytanie, które próbujesz utworzyć, można je łatwo zmodyfikować, aby wykonać to samo zadanie w bardziej przejrzysty sposób. –

Odpowiedz

5

Zapytanie zadziałało po użyciu funkcji wielokrotnego wyboru.

Q.multiselect(fromRooms);