tl; dr
Невозможно заставить фильтр Hibernate работать со встроенным свойством id.
Пример проекта для воспроизведения проблемы здесь
Актуальный вопрос
Я довольно долго борюсь с этим запросом.
Предположим, приведен следующий пример сопоставления сущностей:
@Entity
class Client {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "client_id")
@Basic(optional = false)
private Integer id;
@Basic(optional = false)
private String name;
@OneToMany(mappedBy = "client")
private List<CarRent> rentHistory;
// ... getters and setters
}
@Entity
class Car {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "car_id")
@Basic(optional = false)
private Integer id;
@Basic(optional = false)
private String foo;
// ... getters and setters
}
@Entity
class CarRent {
@EmbeddedId
private CarRentKey carRentKey;
@MapsId("clientId")
@ManyToOne()
@JoinColumn(name = "client_id", nullable = false, insertable = false, updatable = false)
private Client client;
@MapsId("carId")
@ManyToOne()
@JoinColumn(name = "car_id", nullable = false, insertable = false, updatable = false)
private Car car;
@Basic(optional = false)
private String bar;
// ... getters and setters
}
@Embeddable
class CarRentKey {
private int clientId;
private int carId;
@Column(name = "date_due")
private Date dateDue;
// ... getters and setters
}
Мне нужно выбрать всех Клиентов с этимRentHistory заполняется CarRents с определенной даты.Следующий запрос отлично подойдет для меня:
from Client cl
left outer join fetch c.rentHistory as rent with rent.car = c and rent.dateDue = :date
Но Hibernate продолжает подсказывать мне использовать фильтр при извлечении объединения в исключении.
Я пытался
@Entity
@FilterDef(name="dateDueFilter", parameters= {
@ParamDef( name="dateDue", type="date" ),
})
@Filters( {
@Filter(name="dateDueFilter", condition="dateDue = :dateDue"),
})
class CarRent {
// ...
}
но потом, когда я запускаю свой запрос как:
EntityManager em;
// ...
Session hibernateSession = em.unwrap(Session.class);
hibernateSession.enableFilter("dateDueFilter").setParameter("dateDue", dateDue);
em.createQuery("from Client cl"
+ "left outer join fetch c.rentHistory");
List<Client> clientList = q.getResultList();
// clientList contains CarRent of all dates
Фильтр просто игнорируется.Тот же результат с condition="carRentKey.dateDue = :dateDue"
и condition="date_due = :dateDue"
.
Я использую фильтры для других левых внешних объединений по тому же запросу, и они работают просто отлично.Но это одно отношение, которое развивает встроенный параметр, я не могу найти способ заставить его работать.
Возможно ли это?Есть ли альтернативы?
PS: фильтрация в секции where, например, from Client cl left outer join fetch c.rentHistory as rent where rent.dateDue is null or rent.dateDue = :date
, не подходит, так как мой реальный запрос имеет другие объединения, результаты которых фильтруются и становятся очень медленными, когда я делаю это.