How to retrieve a complex class and its members using Hibernate Projection?

前端 未结 4 563
星月不相逢
星月不相逢 2021-01-04 09:08

I have a class as following that need to retrieve from DB using Hibernate. The problem is my class has multiple members and majority of them are classes, how can I retrieve

相关标签:
4条回答
  • 2021-01-04 09:21

    I am not sure if you can use QueryOver but it would be very easy for these kind of tasks.

    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();
    

    Create a StudentModel DTO to have the results. This is just a hint to start with, you can modify this according to your requirement. I hope this will work. :)

    0 讨论(0)
  • 2021-01-04 09:23

    Because you have a List of Courses and a Set of Cars, you can simply fetch the whole graph in a single query:

    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
    

    Because you are fetching two collections, this query will generate a Cartesian Product, so you need to make sure that the selected children collections don't have too many entries.

    If you don;t want to run into a Cartesian product, you can simply run this query:

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

    and then you access the dealer.cars to fetch that collection with a separate query:

    Student s = ...;
    s.getDealer().getCars().size();
    
    0 讨论(0)
  • 2021-01-04 09:33
        // 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 讨论(0)
  • 2021-01-04 09:34

    If high performences are not a concern, then you should let Hibernate do his work. Just use the getters of you entities. For exemple:

    Student student1 = session.get(Student.class, 1L);
    List<Course> courses = student1.getCourses();
    Dealer dealer = student1.getDealer();
    Set<Car> cars = dealer.getCars();
    
    0 讨论(0)
提交回复
热议问题