2015-05-26 61 views
2

我有兩個實體具有單向惰性關係。其中一個有一個命名實體圖。這裏是(getter和setter方法不是由於可讀性上市)實體:條件API和實體圖

@Entity 
    @NamedEntityGraph (
      name = "Sms.fetchSims", 
      attributeNodes = { 
        @NamedAttributeNode("sim") 
      } 
    ) 
    public class Sms { 
     @Id 
     @GeneratedValue (strategy = GenerationType.AUTO) 
     private Long id; 
     @NotNull 
     private Timestamp date; 
     @NotNull 
     private String sender; 
     @NotNull 
     private String content; 

     @NotNull 
     private Direction direction; 

     @NotNull 
     @ManyToOne (fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) 
     private Sim sim; 
    } 

    @Entity 
    public class Sim { 
     @Id 
     @GeneratedValue (strategy = GenerationType.AUTO) 
     private long id; 

     @NotNull 
     private long IMSI; 

     private String MSISDN; 
     private String provider; 
     private Timestamp lockedDate; 
    } 

當我使用實體管理器find()方法與此實體圖形抓取任何短信,我得到一個SIM卡的短信。 但我希望能夠通過sim id找到smses。這就是爲什麼我爲此創建了一個標準api查詢。

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 

    EntityGraph eg = entityManager.getEntityGraph("Sms.fetchSims"); 

    CriteriaQuery<Sms> cq = cb.createQuery(Sms.class); 
    Root<Sms> smses = cq.from(Sms.class); 
    Join<Sms, Sim> sims = smses.join(Sms_.sim); 
    cq.where(cb.equal(sims.get(Sim_.id), simId)); 
    cq.orderBy(cb.desc(smses.get(Sms_.date))); 

    return entityManager 
     .createQuery(cq) 
     .setHint("javax.persistence.fetchgraph", eg) 
     .setMaxResults(1000) 
     .getResultList(); 

正如你看到的,我設置了實體圖形這裏使用類型查詢的setHint方法,但是SIM是從來沒有進賬,這是場甚至沒有在結果SQL上市。我能做些什麼來使實體圖與標準api一起工作?

我知道我可以強制轉換smses.fetch(Sms_.sim)加盟,但我得到醜陋的警告,這種方法看起來像一個骯髒的黑客我。

我與Hibernate和wildfly-8.2.0.Final應用服務器的工作。

+0

兩個實體圖和標準查詢看起來很好。使用原生SQL查詢數據時它工作嗎?像'選擇我。* FROM短信中號INNER JOIN SIM我ON m.sim_id = i.id ORDER BY m.date' – wypieprz

+0

@wypieprz,當然如果我使用SQL,它的工作,因爲我想要的。問題是當它不符合標準api :) – Wyvie

回答

0

是啊,男人,對不起。休眠時有一個b u g,在4.3.9.Final之後修復。 這裏的查詢由4.3.9生成:

DEBUG - org.hibernate.SQL - 
select 
    sms0_.id as id1_1_0_, 
    sim1_.id as id1_0_1_, 
    sms0_.content as content2_1_0_, 
    sms0_.date as date3_1_0_, 
    sms0_.direction as directio4_1_0_, 
    sms0_.sender as sender5_1_0_, 
    sms0_.sim_id as sim_id6_1_0_, 
    sim1_.IMSI as IMSI2_0_1_, 
    sim1_.MSISDN as MSISDN3_0_1_, 
    sim1_.lockedDate as lockedDa4_0_1_, 
    sim1_.provider as provider5_0_1_ 
from 
    Sms sms0_ 
inner join 
    Sim sim1_ 
     on sms0_.sim_id=sim1_.id 
where 
    sim1_.id=1 
order by 
    sms0_.date desc limit ? 

和下面就4.3.8查詢:

DEBUG - org.hibernate.SQL - 
select 
    sms0_.id as id1_1_, 
    sms0_.content as content2_1_, 
    sms0_.date as date3_1_, 
    sms0_.direction as directio4_1_, 
    sms0_.sender as sender5_1_, 
    sms0_.sim_id as sim_id6_1_ 
from 
    Sms sms0_ 
inner join 
    Sim sim1_ 
     on sms0_.sim_id=sim1_.id 
where 
    sim1_.id=1 
order by 
    sms0_.date desc limit ?