2010-09-25 41 views
1

我正在學習JPA並遇到問題。我的主要問題是當我加入我的實體,不太明白爲什麼即時獲得結果我是...和它真的放緩我的進步,如果有人可以幫助我會非常偉大。意外的JPA結果

實體來說

學院

@Entity 
@NamedQueries({ 
    @NamedQuery(name=College.allCollegeQuery,query="SELECT col FROM College col"), 
    @NamedQuery(name=College.collegeStudentJoinQuery,query="SELECT DISTINCT col FROM College col JOIN FETCH col.students"), 
    @NamedQuery(name=College.collegeStudentBasicJoinQuery,query="SELECT col FROM College col JOIN col.students s") 
}) 
public class College { 

    public static final String allCollegeQuery = "allCollegeQuery"; 
    public static final String collegeStudentJoinQuery = "collegeStudentJoinQuery"; 
    public static final String collegeStudentBasicJoinQuery = "collegeStudentBasicJoinQuery"; 

    @Id 
    @GeneratedValue 
    private long id; 
    private String name; 

    @OneToMany(mappedBy="college") 
    private List<Student> students; 

    public long getId() { 
     return id; 
    } 
    public void setId(long id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 

    public List<Student> getStudents() { 
     return students; 
    } 
} 

學生

@Entity 
@NamedQueries({ 
    @NamedQuery(name=Student.allStudentsQuery, query="SELECT stu FROM Student stu"), 
    @NamedQuery(name=Student.studentsCollageQuery, query="SELECT stu.college FROM Student stu WHERE stu.id = :id"), 
    @NamedQuery(name=Student.studentsWithCollageIDQuery, query="SELECT stu FROM Student stu WHERE stu.college.id = :id") 
}) 
public class Student { 

    public static final String allStudentsQuery = "allStudentsquery"; 
    public static final String studentsCollageQuery = "studentsCollageQuery"; 
    public static final String studentsWithCollageIDQuery = "studentsCollagewithIDQuery"; 

    @Id 
    @GeneratedValue 
    private long id; 
    private String name; 

    @ManyToOne 
    private College college; 

    public long getId() { 
     return id; 
    } 
    public void setId(long id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 

    public College getCollege() { 
     return college; 
    } 
    @XmlTransient 
     public void setCollege(College college) { 
      this.college = college; 
     } 
    } 

好了,所以我的目標是查詢所有學院的,並返回所有有關他們的學生。 我期待我的命名查詢做

SELECT col FROM College col JOIN col.students s 

我的性反應是(通過GlassFish的測試器接口調用)

<return> 
     <id>1</id> 
     <name>"Bournemouth</name> 
    </return> 
    <return> 
     <id>1</id> 
     <name>"Bournemouth</name> 
    </return> 
    <return> 
     <id>1</id> 
     <name>"Bournemouth</name> 
    </return> 
    <return> 
     <id>1</id> 
     <name>"Bournemouth</name> 
    </return> 

正如你可以imagen畫質這所大學只存在於數據庫中一次,但我知道這個大學實體有四名學生(我猜爲什麼它重複了)。 該解決方案我和那種希望將財產以後像(在須藤XML一種方式)

<return> 
    <id>1</id> 
    <name>Bournemouth</name> 
    <students> 
    <student> 
    </student> 
    </students> 
</return> 

任何幫助提示或指針將greatfuly recived 感謝

------- - - - - - - - - - - 附加信息 - - - - - - - - - - - - - - -

所以我執行的SQL日誌帕斯卡好心建議其在調用該方法genorates

SELECT DISTINCT t1.ID, t1.NAME, t0.ID, t0.NAME, t0.college_Id FROM STUDENT t0, COLLEGE t1 WHERE (t0.college_Id = t1.ID) 

我也在我的數據庫中測試了上述腳本,其結果如我所期望的JPA返回。

ID name    id  name  col_id 
1 "Bournemouth 2 James 1 
1 "Bournemouth 3 Rich 1 
1 "Bournemouth 1 Jon 1 
1 "Bournemouth 4 tom 1 

所以我想這意味着在我的JPA安裝程序中必須有一個問題? 顯然不能正確重新包裝結果。

再次感謝

-----------更新--------------------------- 進一步從帕斯卡建議我打印數據到服務器日誌切出 測試儀接口。

public List<College> getCollageWithStudents(){ 
    List<College> s = null; 
    try{ 
     Query query = em.createNamedQuery(College.collegeStudentBasicJoinQuery); 
     s = query.getResultList(); 

     for (int i = 0; i < s.size(); i++) { 
       College c = (College) s.get(i); 
       System.out.println("College "+c.getId() + " "+c.getName()); 
       System.out.println("Amt Students: "+c.getStudents().size()); 
       for (int j = 0; j < c.getStudents().size(); j++) { 
        Student stu = (Student) c.getStudents().get(j); 
        System.out.println(stu.getId() + " "+stu.getName()); 
       } 
      } 
    }catch (Exception e) { 
     System.out.println(e.toString()); 
    } 
    return s; 
} 

結果是應該的,但這仍然沒有反映在Glassfish界面中。

INFO: College 1 "Bournemouth 
INFO: Amt Students: 4 
INFO: 2 James 
INFO: 3 Rich 
INFO: 1 Jon 
INFO: 4 tom 

回答

1

您當前的查詢正在執行INNER JOIN,因此在兩個表中至少有一個匹配項時返回行。換句話說,你會得到每個StudentCollege,它有一個College(這就解釋了爲什麼你在這裏獲得4倍於伯恩茅斯)。

什麼:

SELECT DISTINCT c 
FROM College c JOIN FETCH c.students 

,將返回不同的CollegeStudent(和協會)。

+0

感謝Pascal的回覆,我對上述內容感到滿意,只有接縫才能完成大學部分的查詢,換句話說,它並不是爲了獲取部分內容。 – Jon 2010-09-26 09:33:35

+0

@Jon我建議激活SQL日誌記錄以查看究竟發生了什麼,但我確信這個查詢確實也會獲取學生(即,您的學生已加載學生)。 – 2010-09-26 14:18:10

+0

@Pascal我已添加sql日誌記錄,並將結果添加到上述查詢中。謝謝 – Jon 2010-09-28 20:22:40