Hi guys,
I’ve discovered the existence of Vaadin 2 days ago and I love what I see so far, congrats guys!
I struggle with simple data binding with Hibernate for my prototype, and would love some advice/recommendation.
I’ve a long/strategic question that any Vaadin-Hibernate developer should have asked to himself, and count on your experience to answer.
The web site, JavaBlackBelt.com, is layered with
- a presentation layer (call the service layer, and may call a dao directly for a query)
- a Service layer (business logic, use the dao layer)
- a Dao layer (JPA queries, and simple save operation)
I’m doing a prototype with Vaadin as the presentation layer.
The application uses Spring and the Open session in view pattern (a filter to open/close the hibernate session).
I don’t want JPA entities to remain in memory between 2 requests. It would bring old-dirty data problems and concurrency side effects.
In the current application, for each request, I re-query everything I need. I rely on the hibernate 1st land 2nd level cache mechanism to limit the load on the DB.
For example, I don’t keep a User instance in the session. Instead, I keep the user id and re-query the user from hibernate for each request.
In my Vaadin prototype, I’ve a Vaadin Button and Table.
In the ClickListener, of the button, I:
1- call the Dao layer to query auctions.
List auctionItemListDB = daoFacade.getAuctionItemDao().getAll();
2- Put these auctions in a BeanItemContainer
BeanItemContainer bid = new BeanItemContainer(auctionItemList);
3- Attach the BeanItemContainer to the table
auctionTable.setContainerDataSource(bic);
4- Try to limit the displayed columns to “id, name, openDate”.
Object[] visibleCols = {“name”, “initPrice”, “openingDate”};
auctionTable.setVisibleColumns(visibleCols);
It fails at step 3, with a LazyInitializationException on AuctionItem.bids.
The bids property is a collection of Bids (1 to many relationship).
I figured out to include the vaadin application url in the org.springframework.orm.hibernate3.support.OpenSessionInViewFilter, and it works fine.
But it brings a question: why does the Table touch the AuctionItem.bids property? I don’t want the Vaadin Table to touch the bids property, but it does.
How to prevent that?
I tried to perform step 4 before step 3 (which is not allowed by the API, but I used a workaround), with no effect: the Table still tries to access the bids property.
Vaadin probably contains a simple way to express that, and I don’t know it.
[font=Courier New]
auctionTable = Table( use auctionItemList, and limit yourself to {“name”, “initPrice”, “openingDate”}).
[/font]
I’ve read the article “Using Hibernate with Vaadin” - http://vaadin.com/wiki/-/wiki/Main/Using%20Hibernate%20with%20Vaadin?p_r_p_185834411_title=Using%20Hibernate%20with%20Vaadin
And I had a look at the HbnContainer class.
I don’t feel comfortable with it because the HbnContainer touches the Hibernate Session. I don’t want the conainter to merge any entity under the covers, for example. I leave that to the Dao layers through explicit calls.
Let’s take a little bit more complete scenario to see what should be kept in memory and when/who triggers Hibernate.
Let’s say that when I double click on a row of the Vaadin Table, I popup a modal window with an edit form. The Form/Window contains a save and cancel button.
Let’s see when my code is activated:
-
Request 1: My table fills with data.
I call the Dao to get a list of 200 Pojos, and I give it to the Vaadin Table.
The Vaadin Table keeps them in memory (to refesh when I scroll for example?). -
Request 2: Double click on a row.
I get the concerned Pojo from the Vaadin Table, I extract the id and I throw the instance of the Pojo away.
I get a fresh instance of the Pojo from the DB (with the ID, explicit Dao call) and create a new Vaadin Windows/form to edit it. I fill the text fields with the Pojo properties. -
Request 3: User presses the save button.
I get the concerned Pojo from the form window, I extract the id and I throw the instance of the Pojo away.
I get a fresh instance of the Pojo from the DB (with the ID), ask the form to transfer the edit fields in the property of the fresh Pojo, and persist the fresh Pojo through an explicit Dao call.
Does this makes sense to you?
How do I do the binding of step 3 with Vaadin (put form data into fesh Pojo, not into the initial old Pojo)?
Summary -------
Question 1: How to make the Vaadin Table not touch AuctionItem.bids?
auctionTable = Table( use auctionItemList, and limit yourself to {“name”, “initPrice”, “openingDate”}).
Question 2: Does my scenario with request scoped transaction, and old pojos throw away, make sense to you with Vaadin? How do I do the binding of step 3 (put form data into fresh Pojo)?