2012-07-13 33 views
0

我最近開始使用Hibernate和我試圖讓周圍所有的註解我的頭,並確保我做的事情正確。我有兩個表「用戶」和「user_friends」類似於下面Java的Hibernate的註解(@JoinTable,@Filter)

+------+------+-------+------+ 
| id | name | email | etc. | 
+------+------+-------+------+ 

和用戶的朋友表

+--------+---------+----------+ 
| userid | buddyid | accepted | 
+--------+---------+----------+ 

現在,在SQL我跑,看起來類似於

查詢
SELECT u.id AS id, u.name AS username, u.email AS email FROM user_friends 
INNER JOIN users AS u ON u.id = '1' WHERE buddyid = '2' AND ACCEPTED = 1 UNION ALL 
SELECT u.id as id, u.name AS username, u.email AS email FROM user_friends 
INNER JOIN users AS u ON u.id = '2' WHERE buddyid = '1' AND ACCEPTED = 1; 

我在Java中設置了一個時尚與此類似

@Entity 
@Table(name="users") 
public class User { 

    @Id 
    @GeneratedValue 
    private int id; 

    private int name; 
    private int email; 

    private DateTime registerDate; 
    private DateTime lastActivity; 

    private int currency; 
    private int seasonCurrency; 

    @OneToMany(fetch=UserBuddy.class, mappedBy="user", fetch=FetchType.LAZY) 
    @JoinColumn(name="userid") 
    @Filter(name="messengerBuddyFilter", condition="accepted=1") 
    private Set<UserBuddy> _buddies; 
} 

@Entity 
@Table(name="user_friends") 
public class UserBuddy { 

    private int id; 
    private int name; 
    private int email; 
} 
有兩個班

我之前問過這個問題,但仍然沒有能夠得到這個工作如何我喜歡它。我需要能夠返回一組UserBuddy.class,其中包含該Buddy的名稱和電子郵件,而不是其他任何內容,而不是其註冊時間等(通過使用User類映射)。我也遇到了困難,確保它只返回那些已經接受該請求(○= 1)

誰能提供任何建議,哥們?

+1

如果'接受'總是反身關係(朋友必須相互接受),那麼可以通過總是存儲buddy1 2012-07-13 19:00:35

+0

從來沒有想過要這樣做。永遠不能擺脫某種東西要告訴我他們是否是朋友的心態(例如,'接受'的專欄)! – DominicEU 2012-07-13 19:05:56

回答

1

您需要使用本機查詢,如果您正在使用JPA(和命名原生查詢使用Hibernate和JPA是有問題的)或IIRC SQL查詢,如果只使用純休眠。

這可能會實現...只是這樣做很快,使用它作爲一個起點。例如,您在JPA實體管理器名爲EM定義爲類的成員變量

@PersistenceContext(unitName = "MyPersistenceUnit_PU") 
private EntityManager em; 

...

一些方法...

List<UserBudy> buddyList = new <>ArrayList(); 
Query q = createNativeQuery("SELECT u.id AS id, u.name AS username, u.email AS email " 
          + "FROM user_friends " 
          + "INNER JOIN users AS u " 
          + "ON u.id = '1' " 
          + "WHERE buddyid = '2' " 
          + "AND ACCEPTED = 1 " 
          + "UNION ALL " 
          + "SELECT u.id as id, u.name AS username, u.email AS email " 
          + "FROM user_friends " 
          + "INNER JOIN users AS u " 
          + "ON u.id = '2' " 
          + "WHERE buddyid = '1' " 
          + "AND ACCEPTED = 1"); 
List<UserBudy> buddyList = (List<UserBudy>)em.getResultList); 

這個例子是不是一個「命名」本機查詢。這與內聯類似於POJDBC(普通的舊jdbc)。就像我說的,如果你打算嘗試使用JPA和Hibernate創建一個NamedNativeQuery,你會得到「某種或其他未實現的例外」。 Hibernate永遠不支持使用JPA的命名本機查詢。它仍然在他們的bug追蹤器中(已經有5到6年了),看起來他們不會給老鼠屁股修理它。總的來說,在使用PostgreSQL的時候,使用Hibernate的問題比使用Eclipselink的時候少,所以我現在可以忍受它。 :)

IIRC如果你是用純休眠要做到這一點,你會創建一個Hibernate會話對象,而不是一個JPA EM對象,並使用createSQLQuery代替。除此之外幾乎是一樣的。

session.createSQLQuery("..."); 

如果沒有足夠的幫助,您現在應該至少有足夠的信息來弄明白。

這裏是一個鏈接,如果你想嘗試你是什麼使用純JPA之後。關於本文的一半,請查找「訂單項摘要」示例。

http://www.oracle.com/technetwork/articles/vasiliev-jpql-087123.html

當你正在處理的JPA您要加入的實體,而不是表記住。無論如何,那篇文章是我見過的最清晰的文章之一,展示了它的很多作品。問候。

+0

非常感謝您的回答。欣賞它。 – DominicEU 2012-07-13 19:05:04