2

I am giving a detailed explanation of the application flow I have in my application. I am working on a Database viewer application. User can see all the records (rows) in my DB with this application and can edit from UI. This application is working fine. Now I want to implement Optimistic Locking for that I have created a version field in DB. Now I struck with a design issue,

Until now in my application, when a user view the record and want to edit it, in my controller method I am doing a Hibernate load and displaying the result in edit JSP page. Now when a user clicks 'Save' on the page I have to do save the record. Because it is a very complex entity, I am re populating this entity from DB and making the changes and doing Hibernate save or update.

Now, I want to implement versioning, so I no longer want to re populate the entity before I do save or update. Somehow I want to keep my complex entity safe and use this when I want to update. JSP hidden form fields are not possible in my case. Where can I keep my entity safe until user clicks 'Save' button and use it to persist in db ?. What are the possible and best approaches.

Update:

I have reviewed various posts in internet and planning to implement EHcache framework.

EagleRider
  • 73
  • 1
  • 8
  • 2
    The session would be an obvious place. http://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpSession.html – Alan Hay Oct 04 '16 at 18:17
  • @AlanHay But somehow, now when I do (session.getAttribute("obj")).equals(DAO.get(...)) are not matching. I am getting false. I have verified eqauls method on all member variables of object. They should be equal right ? – EagleRider Oct 04 '16 at 18:40

2 Answers2

1

You have two options:

Store the state on the server (in session) or on the client (in hidden form fields). You can protect client data using an HMAC, but this takes processing time. I'd recommend server-side session for convenience

My answer here includes an example of how to use session with optimistic locking: Spring MVC: Validation, Post-Redirect-Get, Partial Updates, Optimistic Concurrency, Field Security

Community
  • 1
  • 1
Neil McGuigan
  • 46,580
  • 12
  • 123
  • 152
  • is there any option apart from using session ?. Why I am insisting is, We don't want to over burden server (we want to stop memory consumption for more sessions). Is there a way to cache the object using Hibernate caching or third party assistance ? – EagleRider Oct 04 '16 at 21:17
  • @EagleRider you can store the state in hidden form fields in the browser – Neil McGuigan Oct 04 '16 at 21:20
  • our object is very complex. almost two hundred fields. So searching for alternatives. Thank You for helping. – EagleRider Oct 04 '16 at 21:22
  • @EagleRider 1. you've done something wrong if a table in an operational database has 200 fields. 2. I said you have two options and listed them. Pick one or the other. Either use more memory (session) or more bandwidth/processor (client). 3. RAM is $30/8GB these days – Neil McGuigan Oct 04 '16 at 21:27
  • Ya. If we don't find any alternative we may end up using hidden id, version number in form. But we are still building application so trying to gather all possible solutions. I appreciate your patience and your input is much helpful . :) Thank you. – EagleRider Oct 04 '16 at 21:30
  • sorry my wording is wrong. Our object has so many member variables which again have multiple member variables. We are almost want to cache high level object. Our tables are pretty reasonable with 20-30 columns. – EagleRider Oct 04 '16 at 21:33
0

That is what @SessionAttributes is for. Regardless of how you need to store the object somewhere, you can try and mess around and figure out your own or use a default solution.

@SessionAttributes("your-model")
@Controller
public class YourController {

    @RequestMapping(method = GET)
    public String show(long id, Model model) {
        // Get your entity
        model.addAttribute("your-model", entity);
        return "edit";
    }

    @RequestMapping(method = POST) {
    public String show(@Valid @ModelAttribute("your-model") YourModel model, SessionStatus status) {
        // Save your entity
        status.setComplete();
        return "list";
    }
}

Regardless of your way of implementing, you still need to have your data (partially) in memory. And as mentioned before you can try hacking in your own solution, or use the default spring mechanism.

Solutions like EhCache still cache things in memory, can offload to other storage if needed. The same you can configure for your sessions (depending on your container). Or use something like Spring Session to have different options.

Anyway I would start with storing it in the session, then start measuring and if it really becomes an issue, figure out another way to store your entities in between requests. But start simple, measure and then improve instead of trying to solve issues which might occur.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • @m-deinum Issue using session in my case is distributed production environment. Their is no guarantee that every request will go same server. How can I use session in such case. – EagleRider Oct 10 '16 at 14:21
  • As mentioned you can use Spring Session (the link is included in the answer). – M. Deinum Oct 11 '16 at 06:02