亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 @EmbeddedId 屬性中使用 Hibernate 的 @Filter 注釋

如何在 @EmbeddedId 屬性中使用 Hibernate 的 @Filter 注釋

慕的地8271018 2022-06-04 09:39:34
無法使 Hibernate 過濾器與嵌入的 id 屬性一起使用。在此處重現問題的示例項目實際問題我在這個查詢上苦苦掙扎了很長一段時間。假設以下實體映射示例:@Entityclass 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}@Entityclass Car {    @Id    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "car_id")    @Basic(optional = false)    private Integer id;    @Basic(optional = false)    private String foo;    // ... getters and setters}@Entityclass CarRent {    @EmbeddedId    private CarRentKey carRentKey;    @MapsId("clientId")    @ManyToOne()    @JoinColumn(name = "client_id", nullable = false, insertable = false, updatable = false)    private Client client;}我需要從某個日期獲取所有帶有 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不是一個選項,因為我的真實查詢有其他連接,結果被過濾并且當我這樣做時變得非常慢。
查看完整描述

2 回答

?
呼如林

TA貢獻1798條經驗 獲得超3個贊

原來我在這種情況下濫用了@Filter 注釋。


Vlad Mihalcea 幫助我解決了我在 Hibernate 論壇上的帖子的問題


根據他的方向,我設法在沒有過濾器的情況下解決了這個問題,使用沒有獲取的連接查詢和結果轉換器。


該示例的解決方案是:


org.hibernate.query.Query<Client> q = em.createQuery("select cl, cr " + 

        "from Client cl " + 

        "join CarRent cr on cr.client = cl and cr.carRentKey.dateDue = :date")

        .setParameter("date", exampleDate)

        .unwrap(org.hibernate.query.Query.class).setResultTransformer(new BasicTransformerAdapter() {

            @Override

            public List transformList(List list) {

                Map<Serializable, Client> clientMap =

                        new LinkedHashMap<>(list.size());


                for (Object entityArray: list) {

                    if (Object[].class.isAssignableFrom(entityArray.getClass())) {

                        Client client = null;

                        CarRent carRent = null;


                        Object[] tuples = (Object[]) entityArray;


                        for (Object tuple : tuples) {

                            em.detach(tuple);


                            if (tuple instanceof Client) {

                                client = (Client) tuple;

                            }

                            else if (tuple instanceof CarRent) {

                                carRent = (CarRent) tuple;

                            }

                            else {

                                throw new UnsupportedOperationException(

                                    "Tuple " + tuple.getClass() + " is not supported!"

                                );

                            }

                        }


                        if (client != null) {

                            if (!clientMap.containsKey(client.getId())) {

                                clientMap.put(client.getId(), client);

                                client.setRentHistory(new ArrayList<>());;

                            }

                            if (carRent != null) {

                                client.getRentHistory().add(carRent);

                            }

                        }

                    }

                }

                return new ArrayList<>(clientMap.values());

            }

        });


List<Client> clientList = q.getResultList();


查看完整回答
反對 回復 2022-06-04
?
楊__羊羊

TA貢獻1943條經驗 獲得超7個贊

我不知道,如果我理解正確,但是這個:


em.createQuery("from Client cl"

+ "left outer join fetch c.rentHistory");

不使用@Embeddable應該過濾的。


編輯:


您需要使用Session已設置的。用它打開事務并查詢結果:


hibernateSession.openTransaction();

results = hibernateSession.createQuery(...).list();

hibernateSession.close();


查看完整回答
反對 回復 2022-06-04
  • 2 回答
  • 0 關注
  • 118 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號