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 them?
@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);
..
}
I need to retrieve student id 1 and all its courses, its dealer and list of dealers' cars.
My projection is as following but it does not return anything.
...
.setProjection(Projections.projectionList()
.add(Projections.property("friends.cars").as("cars")
...
// 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));
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With