2015-04-17 26 views
12

Mam klasy w następujący sposób, że trzeba pobrać z DB przy użyciu Hibernacja. Problem polega na tym, że moja klasa ma wielu członków, a większość z nich to klasy, w jaki sposób mogę je odzyskać?Jak odzyskać złożoną klasę i jej elementy za pomocą aplikacji Hibernate Projection?

@Entity 
public class Student { 
    @Id 
    long id; 
    String name; 
    String fname; 
    @OneToMany 
    List<Course> courses; 
    @ManyToOne 
    Dealer dealer; 
    ... 
} 

@Entity 
public class Dealer { 
    @Id 
    long id; 
    String name; 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "cr.dealer", cascade = CascadeType.ALL) 
    Set<Car> cars = new HashSet<Cars>(0); 
    .. 

} 

Potrzebuję pobrać identyfikator ucznia 1 i wszystkie jego kursy, jego sprzedawcę i listę samochodów dealerów.

Moja projekcja wygląda następująco, ale nic nie zwraca.

... 
    .setProjection(Projections.projectionList() 

    .add(Projections.property("friends.cars").as("cars") 
    ... 

Odpowiedz

1

Ponieważ masz listę kursów i zestaw samochodów, można po prostu pobrać cały wykres w jednym zapytaniu:

select s 
from Student s 
left join fetch s.courses 
left join fetch s.dealer d 
left join fetch d.cars 
where s.id = :id 

Ponieważ pobierasz dwie kolekcje, to zapytanie wygeneruje produkt kartezjański, więc musisz upewnić się, że wybrane zbiory podrzędne nie mają zbyt wielu wpisów.

Jeśli don; t chcesz uruchomić na iloczyn kartezjański, wystarczy uruchomić tę kwerendę:

select s 
from Student s 
left join fetch s.courses 
left join fetch s.dealer d 
where s.id = :id 

a następnie uzyskać dostęp do dealer.cars pobrać tę kolekcję z oddzielną zapytania:

Student s = ...; 
s.getDealer().getCars().size(); 
+0

Dziękuję za odpowiedź, czy mógłbyś rzucić okiem na moje pytanie na http://stackoverflow.com/questions/29980421/how-to-retireve-a-set-member-objects-using-hibernate – Jack

0

Jeśli wysoka wydajność nie jest problemem, należy pozwolić Hibernate wykonać swoją pracę. Po prostu użyj modułów pobierających z ciebie. Dla exemple:

Student student1 = session.get(Student.class, 1L); 
List<Course> courses = student1.getCourses(); 
Dealer dealer = student1.getDealer(); 
Set<Car> cars = dealer.getCars(); 
+1

Dzięki, ale wysoka wydajność powinna być wzięta pod uwagę. – Jack

4
// Projection is not needed, Hibernate will load child values as shown below 

    Student student = session.get(Student.class); 
    List<Course> courses = student.getCourses(); 
    Dealer dealer = student.getDealer(); 

    // If u want records only where child records are present, u can use LEFT_OUTER_JOIN 

    Criteria criteria = getHibernateSession().createCriteria(Student.class); 
    criteria.createAlias("Course", "Course", JoinType.LEFT_OUTER_JOIN); 

    // If u want to use Projections for performance, u have to add each and every column in projection 

    Criteria criteria = getHibernateSession().createCriteria(A.class); 
    criteria.createAlias("b", "b", JoinType.INNER_JOIN); 
    criteria.createAlias("b.r", "b.r", JoinType.INNER_JOIN); 
    criteria.createAlias("b.c", "b.c", JoinType.LEFT_OUTER_JOIN); 
    ProjectionList projectionList = Projections.projectionList(); 
    projectionList.add(Projections.groupProperty("column1")); 
    projectionList.add(Projections.property("column2")); 
    projectionList.add(Projections.property("column3")); 
    criteria.setProjection(projectionList); 
    criteria.setResultTransformer(Transformers.aliasToBean(Table.class)); 
+0

Dzięki za odpowiedź , Mam nowy problem z tym i napisałem nowe pytanie do tego problemu proszę spojrzeć dzięki, http://stackoverflow.com/questions/29980421/how-to-retireve-a-set-list-of-member-objects -używanie-hibernacja – Jack

0

nie jestem pewien, czy można użyć QueryOver ale byłoby to bardzo łatwe dla tego rodzaju zadań.

Student student = null; 
Dealer dealer = null; 
Course course = null; 
Car car = null; 

var myStudent = Session.QueryOver<Student>(() => student) 
.Left.JoinQueryOver(() => student.courses,() => courses) 
.Left.JoinQueryOver(() => student.dealer,() => dealer) 
.Left.JoinQueryOver(() => dealer.cars,() => car) 
.SelectList(list => list 
    .Select(() => student.Name) 
    .Select(() => student.Age) 
    .Select(() => courses.Description) 
    .Select(() => dealer.locaiton) 
    .Select(() => car.Model)) 
    .TransformUsing(Transformers.AliasToBean<StudentModel>()) 
    .List<StudentModel>().AsQueryable(); 

Utwórz DTO StudentModel, aby uzyskać wyniki. To tylko wskazówka na początek, możesz zmodyfikować to zgodnie z wymaganiami. Mam nadzieję, że to zadziała. :)