Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate paginated OneToMany relationship

how can I map a one-to-many relationship in Hibernate where the many-side needs to be paginated? (i.e. you have hundreds or more related objects)
Using the OneToMany annotation (or its xml equivalent) is not useful because loading the one-side object retrieves with it all of its related objects causing a memory disaster (even though you use lazy loading).
A possible approach (which I'm already using) is to add a getter method in a DAO implementation, where you can introduce pagination parameters. However, I can see this is not ideal because you lose some features like cascading (e.g. I have to include setter methods in the DAO class to associate objects). Besides, you lose some OOP sense as the one-side object doesn't have a method to retrieve its related many-side objects. What's the best solution?
To illustrate my point further, let's say I have two classes with the following relationship among them: A has-many B.
I can't write an A.getAllB() method using a OneToMany annotation, as there are hundreds of Bs related to an A. Thus, to paginate the results I create a separate ADaoImpl class with a getAllB() method where I can include pagination params to return just one page of data at a time. Is this correct? Any help will be appreciated.

like image 517
user1607194 Avatar asked Nov 04 '22 17:11

user1607194


1 Answers

I think I would do the same thing you are proposing: Create a new method on my dao that takes pagination parameters and returns the specified page of results. Whether or not you want to keep the children in your parent object is up to you. You can make a transient field for those objects.

  public class Parent {
    @Transient
    private List<Child> children;

  }

  public class ParentDao {

    // Solution 1 - You can keep the parent/child association
    public void loadChildren(Parent parent, int firstResult, int maxResults) {
       // do your query
       parent.setChildren(query.list());
    }

    // Solution 2 - Or just have your dao directly return the children and remove the list from Parent
    public List<Children> getChildren(Parent parent, int firstResult, int maxResults) {
      // do your query
      return query.list();
    }
  }

I know what you mean about breaking your OO feeling of the code. But really pagination is a function of the data layer. Going with the first solution may restore some of that nice "OO" feeling.

like image 88
jeff Avatar answered Nov 15 '22 10:11

jeff