2012-10-19 56 views
0

我有2個模型,帶有@OneToOne關係。我們假設一個模型User和一個模型Player。每個用戶都是玩家,每個玩家都是用戶。ew @ OneToOne與不使用JOIN的播放框架的關係

下面是這2種型號的代碼:

@Entity 
public class User extends Model { 

    @Required 
    public String name; 

    @OneToOne(fetch = FetchType.EAGER) 
    public Player player; 
} 

@Entity 
public class Player extends Model { 

    @Required 
    public String nickname; 

    @Required 
    public Gender gender; 
} 

我將永遠從User訪問Player,我想,當我打開一個用戶,他的球員也被加載(這就是爲什麼我用fetch = FetchType.EAGER )。

所以,我期望(爲了優化的目的),當我加載User時,查詢是JOIN查詢也加載Player。 喜歡的東西:

select u, p from User u join u.player p where u.player_id = p.id 

但是,當我看着查詢計數和查詢調試輸出我可以看到,2個查詢的執行。 喜歡的東西:

select u from User u 
select p from Player p where p.id = ? 

但這不是最優化的,我怎樣才能使JPA執行加入請求讓我User及其Player

坦克你的幫助!

編輯:我使用播放框架1.2.5

回答

2

在用戶類,如您在您的評論注意到,玩家可以爲空

public static void findByIdWithPlayer(Long id) { 
    find("select distinct user from User user left join fetch user.player where user.id=?", id).first(); 
} 
+0

謝謝你的回答,但它不起作用:(當我從查詢中刪除「join fetch user.player」時,它工作(除非它不加載播放器),但使用「join fetch user.player」語句它不起作用:( –

+0

不知道在這種情況下你的問題是什麼,但這是在hql中定義提取的正確語法(http://docs.jboss。 org/hibernate/orm/3.6/reference/en-US/html/queryhql.html#queryhql-joins)。您不必在模型類中定義預先抓取。 –

+0

感謝您的幫助,我設法通過將請求更改爲:從用戶用戶**離開** join fetch user.player where user.id =? –

2

編輯:這個答案只適用於與Ebean播放2.0。

如果您使用Ebean或簡單的JPA,目前尚不清楚。

如果Ebean,如doc解釋,你必須獲取鏈接的實體:

List<User> orders = 
    Ebean.find(User.class) 
     .fetch("player") 
     .findList(); 
+0

我認爲這是普通的JPA,但我不確定,這是由Play Framework處理,應該使用JPA –

+0

從文檔http://www.playframework.org/documentation/2.0.4/JavaEbean看來,你使用Ebean,因爲你的實體正在擴展'Model'類。所以上面提供的代碼應該按預期工作。 –

+0

我正在使用玩框架版本1.2.5,它也是Ebean嗎?我什麼也看不到 –