неожиданные результаты JPA - PullRequest
       21

неожиданные результаты JPA

1 голос
/ 25 сентября 2010

Я изучаю JPA и испытываю проблемы. Моя главная проблема заключается в том, что когда я присоединяюсь к своим организациям и не совсем понимаю, почему я получаю результаты, я… и это действительно замедляет мой прогресс, если кто-то может мне помочь, я был бы очень благодарен.

Entitys

колледж

@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;
    }
}

Student

@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 Tester)

    <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>

Как вы можете себе представить, этот колледж существует только один раз в базе данных, но я знаю, что к этому объекту колледжа привязаны четыре студента (что, я думаю, почему оно повторилось). Решение, на которое я и надеюсь надеяться, будет примерно таким (вроде sudo xml)

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

любые подсказки или подсказки были бы замечательно восприняты Спасибо

--------------------------- Дополнительная информация ------------------ ------------

Итак, я выполнил регистрацию SQL, как любезно предложил Паскаль, которая при вызове метода генерирует

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 Ответ

1 голос
/ 26 сентября 2010

Ваш текущий запрос выполняет INNER JOIN и, таким образом, возвращает строки, если в обеих таблицах есть хотя бы одно совпадение. Другими словами, вы получите College каждого Student с College (и это объясняет, почему вы получаете в 4 раза больше Борнмута здесь).

А как же:

SELECT DISTINCT c 
FROM College c JOIN FETCH c.students

Это вернуло бы различное College, имеющее Studentизвлечение ассоциации).

...