How wicket LoadableDetachable model works
java, wicket
Solution
`LoadableDetachableModel` caches the retrieved object for the duration it is attached. When you `load` the data from the database, all items are there. Then you execute a query to delete a record, but don't update the list. So either you have to change your `onClick` handler to also update the retrieved list, or just detach the model.
There is no magic in LoadableDetachableModel. Take a look at the code below:
List<Person> people = dao.getListOfPeopleAttendingParty();
// assume that the number of people attending the party is 4
assert people.size() == 4;
Person guest = people.get(0);
dao.delete(guest);
// what is the number of people attending the party now?
assert people.size() == ?;
What do you think that `people.size()` is now?
The execution of LoadableDetachableModel is not any different than the code snippet above:
List<Person> people = peopleModel.getObject(); // is called by ListView
// assume that the number of people attending the party is 4
assert people.size() == 4;
Person guest = people.get(0);
dao.delete(guest);
// what is the number of people attending the party now?
assert people.size() == ?;
So: no magic involved, just plain Java and ordinary logic.
PS. The answer to both questions is 4 even though the database no longer holds the guest
Problem
I am trying to understand how Wicket LoadableDetachable model is working. What i understand from the Wicket documentation is in a normal scenario , when the request completes the processing wicket will auto serialize the all components with associated model values. This one will consumes more memory . If we use the LoadableDetachable model at the time of serialization the model values will not get serialized. Is this right? . So it will detach the model object automatically . So For the next request the model value will be reload again automatically? See my below code. ``` public class ProductListPanel extends Column<Product> { @SpringBean private ProductService productService; private List productList; public ProductListPanel(String id) { super(id); class ProductModel extends LoadableDetachableModel { @Override public void detach() { // TODO Auto-generated method stub productList = null; System.out.print("Called Detach Object\n"); } @Override protected Object load() { // TODO Auto-generated method stub productList = productService.findAll(); System.out.print("Called Get Object\n"); return productList; } } System.out.print("Before creating also calling\n"); final ProductModel productModel = new ProductModel(); ListView view = new ListView("list", productModel) { protected void populateItem(ListItem item) { System.out.print("\nBefore start also calling\n"); System.out.print("Before this one is callling \n"); Product result = (Product) item.getModelObject(); item.add(new Label("code", result.getCode())); item.add(new Label("name", result.getName())); final Link deleteLink = new Link("remove", item.getModel()) { @Override public void onClick() { Product product = (Product) getModelObject(); productService.delete(product); } }; item.add(deleteLink); } }; add(view); Link addProductLink = new Link("addProduct") { @Override public void onClick() { // TODO Auto-generated method stub setResponsePage(new AddProduct()); } }; add(addProductLink); productModel.detach(); } } ``` In the above code i am listing all the products from the DB. and i am having Remove link for each product , when we are clicking that link i am removing the product from the DB. After clicking the Remove link the page is not getting refreshed means it still showing the deleted product . if i add this line productModel.detach(); then it is working properly . My question here is why i have to call productModel.detach(); manually? LoadableDetachableModel suppose do automatically right? Please help me