I have an application that exposes a series of Web services. One of my entities has a bunch of one-to-many and many-to-many relations to other entities. My transactionality level is at DAO, and I'd like to keep it there to avoid the persistence context being open too long. Thinking of moving it up to the service level or specially leaving it open for the full request gives me the fears. So I had to mark all associations as eager.
The result is of course that when fetching it Hibernate generates a massive query that is starting to go slow. I went with 'premature optimization is the root of all evil' but it's something that needs to be dealt with already.
My problem is that, given that I want to keep @Transactional
at DAO level, I am down to two (quite similar) options:
Set the associations as lazy, and manually querying DB and setting them before each get of a corresponding property. Thus, where I have
// entity @OneToMany(fetch = EAGER, mappedBy = "user", cascade = {ALL}, orphanRemoval = true) private final Set<Order> orders = new HashSet<>(); // usage user.getOrders()
I'd change to:
// entity
@OneToMany(fetch = LAZY, mappedBy = "user", cascade = {ALL}, orphanRemoval = true)
private final Set<Order> orders = new HashSet<>();
// usage
Set<Order> orders = orderDao.findByUserId(user.getId());
user.setOrders(orders);
user.getOrders()
This doesn't feel right, because I understand that the purpose of having an Hibernate relation is to let Hibernate manage it. On the other hand, I would still have the advantage of having Hibernate managing updates and inserts.
- Remove the relation at Hibernate level altogether, and manage them completely manually. Of course, this is not extremely, but quite painful.
Is there any other option? What's the usual optimization path in cases like this?