Question

To cut a long story short, I'm trying to display menues of restaurants on a website. One page (or URL if you like) should show exactly one menu. The restaurant/menu-thing is not really important at this point, but maybe it helps to make things clearer.

The main entities:

  • Menu (the "container")
  • Category (a Menu has several Categories like appetizers, soft drinks etc..)
  • Item (a Category contains dishes, drinks etc. which are Items)

enter image description here

As mentioned above, the aim is to load a single but whole menu together with all of its categories and the categories' items at once, or at least with a low amount of queries (given a specific menu-id). In a first naive approach, I used the following JPQL-query:

SELECT DISTINCT m FROM Menu m JOIN FETCH m.categories c JOIN FETCH c.items i WHERE m.id = :menuId

The query works as expected, but there is another requirement. As you can see in the drawing above, categories and items have an attribute called orderNo (e.g. 1, 2, 3, 4 ...) - the only purpose of this attribute is to control in which order categories and items inside of categories should appear on the website later on (of course the appetizer category should be rendered before the main dish category, followed by the category for desserts, in simplified terms. Same goes for items inside of categories).

And that's my problem at the moment. The options:

  • let the database do the sort
  • do the sort in my application after having received disordered data

I assume you would prefer the first option like I do, but it is not as easy as I thought (well, it never is..). Simplified versions of my entities look as follows:

@Entity
public class Menu {
    // ...
    @OneToMany(mappedBy="menu")
    private Set<Category> categories;
}

@Entity
public class Category {
    // ...
    @ManyToOne
    private Menu menu;
    @OneToMany(mappedBy="category")
    private Set<Item> items;
}

@Entity
public class Item {
    // ...
    @ManyToOne
    private Category category;
}

My hope was that I could extend the JPQL-query from above with something like ORDER BY i.orderNo asc, c.orderNo asc, but that didn't to the trick. Then I suspected the type Set of being a problem and replaced the two occurences with List. This led to a MultipleBagFetchException ("cannot simultaneously fetch multiple bags"). Is my intention (getting an entity which has a list of sorted categories which have a list of sorted items) not feasible at all with JPA? My JPA provider is Hibernate, but I could change it if necessary.

edit:

Just to give you an idea of the amount of data: the average menu has ~7 categories, each category has ~10 items. If you think my whole model needs to be improved, then I'm open for other approaches.

No correct solution

OTHER TIPS

An idea could be to use @OneToMany reverse mapping and @OrderBy on it.

I think you do no need that query. The following could load a menu given an ID

from Menu m where m.id = ID

That query will fetch your menu object and all reverse mappings will be populated ordered by your @OrderBy annotation

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top