1

I'm using Spring 4 and Hibernate 4. I'm having a problem that it seems a lot of other people have. I want my Spring form to edit only certain properties of an entity, not the whole thing.

By default, if I load a persisted entity, display a few of it's properties in a form for editing, post it to my controller and save it... any property values that were not included in the form are lost. I do understand why this happens, and I'm aware of a few solutions floating around out there.

1) At save-time, load the entity from the db, copy only the properties you want from the model, save.

2) When the form starts, load the entity and use the @SessionAttributes feature to store it in the session between requests.

But I'm not liking either one of these. Maybe I'm missing something, but the solution seems fairly simple. Somewhere, the default Spring web binder is creating a instance of the entity to copy the form properties into. If I could just override that and use the ID to load the persisted entity from the DB, then have Spring's binding use that as the target entity (copying only properties submitted with the form, leaving the others untouched)... then I think that would solve my problem.

I've been looking for how/where I can use a custom WebDataBinder class. I don't see how.... and I'm not even sure if that's the place I should be looking.

Any suggestions?

Thanks!!

EDIT:
I'll give a hypothetical example to try to better explain my problem. Let's say I have an entity class, Customer, that has 50 properties. I have a form for updating the contact info only. This is only 5 properties out of the 50.

street
city
state
zip
phone

If I do this is in a Spring form, when the form is submitted to be saved, Spring creates a new 'blank' entity, populates it with values from the form and passes it to my controller... this is what gets saved. The problem is, since other properties such as, firstName, lastName, customerType, etc, weren't included in the form, Spring leaves them alone and they remain null. When I tell Hibernate to update the entity using this one provided by Spring, Hibernate believes I want firstName, lastName, etc to be null since those are the values I'm providing in the bean. It doesn't know that I only changed a few of them.
So what happens? 45 out of my 50 property values get blown away.

In the comments below, Sp00m suggested a solution that would work... include all the other properties in hidden fields. But for various reasons, that solution is a huge headache for me.

If I could just get Spring to load the entity from the database (instead of creating a new/blank entity) AND THEN populate only those fields that were submitted with the form. I believe that would solve my problem.

A similar discussion (but with the hidden-field solution) can be found here.. http://www.coderanch.com/t/529490/Spring/Spring-MVC-Hibernate-Update-column

user3311662
  • 111
  • 7
  • Another simple solution would be to bind the *non-form properties* to `` tags. – sp00m Apr 28 '14 at 15:01
  • Thanks for your reply. You're right, but I have a LOT of different entity classes with a lot a lot of properties. I have different forms that edit different properties based on various conditions. In my case, that solution is too tedious and error prone. – user3311662 Apr 28 '14 at 15:03
  • 1
    I would suggest adding code and configuration examples, or else its a game of guesses. I can't believe this is default behavior of the framework (nor do I remember having this problem with Spring MVC, but I last used it when Spring 2 was still current); I'd rather suspect the framework is not being applied properly. But without having something to look at, that's me making guesses. – Gimby Apr 28 '14 at 15:19
  • Possible duplicate of [this](http://stackoverflow.com/questions/5022797/protect-specific-fields-when-binding-in-spring)? – MarkOfHall Apr 28 '14 at 15:23
  • Thanks for your comments guys. Steve, no, that is different. I guess maybe I did not explain myself well. I'll edit my initial post to give a more concrete example. But also, here is a link to someone discussing the same problem I'm having. http://www.coderanch.com/t/529490/Spring/Spring-MVC-Hibernate-Update-column – user3311662 Apr 28 '14 at 15:54
  • Have you tried hibernate specific annotation @DynamicUpdate on entity. For updating entity uses dynamic sql generation where only modified columns get reference in the prepared sql statements. For detached entities it is possible only **select-before-update** is enabled – Swathi Apr 29 '14 at 01:21
  • Hi Swathi, I had never heard of that option. Thanks for the suggestion. I gave it at try, but it wasn't working for me for some reason. I'm sure I was doing something wrong, but I ended up figuring out a Spring solution that seems to be working great. – user3311662 Apr 29 '14 at 17:09

1 Answers1

1

So here's the solution that works for me. By adding the following method with the annotation in the controller, Spring uses it to instantiate the entity for binding. Exactly what I needed.

(I had actually tried this out previously, but I hadn't specified the model attribute name in the annotation, which is obviously no good.)

Thanks to all those who commented with suggestions.

@ModelAttribute("entity")
public MyEntity getEntity(@RequestParam(required=false) Integer id)
{ 
    if (id == null)
    {
        return myEntityManager.createEntity(entityClass);
    }
    else
    {
        return myEntityManager.find(entityClass, id);
    }
}
user3311662
  • 111
  • 7