【发布时间】:2019-06-26 10:08:52
【问题描述】:
tl;博士
无法使 Hibernate 过滤器与嵌入的 id 属性一起使用。
重现问题的示例项目here
实际问题
我为这个查询苦苦挣扎了很长一段时间。
假设以下实体映射示例:
@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
}
我需要从某个日期获取所有带有 CarRents 的rentHistory 的客户。以下查询非常适合我:
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 不是一个选项,因为我的真实查询还有其他连接,这些连接的结果会被过滤,并且当我这样做时会变得非常慢。
【问题讨论】:
标签: java postgresql hibernate jpa jpql