1

I'm using Spring and Hibernate in a web application. I have an entity as follow:

@Entity
public class MyClass{
   @Id
   @GeneratedValue
   protected Long id;

   protected String prop1;

   protected String prop2;

   /*
    *  Getters And Setters
    */

}

When I want to update an instance of this entity, I get the instance from client by using jackson as follow:

@Inject
SessionFactory sf;

@RequestMapping("update")
@Transactional
public void update(@RequestBody MyClass myClass){
    sf.getCurrentSession.update(myClass);
}

User data is as follow:

{
   "prop1": "my value1",
   "prop2": "my value2"
}

this work correctly. My problem is when I want to update only prop1. In this state, I have to set prop2 too. If I don't, it update prop2 to null.

How can only update prop without sending prop2 from client to server?

Morteza Malvandi
  • 1,656
  • 7
  • 30
  • 73
  • if you want to have control on the exact update query (i.e., which fields should be included in the query) to be fired, use HQL update statement. Using session.save/update/merge/saveOrUpdate hibernate creates the query internally and you won't have fine grained control that you may need. – Madhusudana Reddy Sunnapu Dec 24 '15 at 09:19
  • You should use spring Data JPA. http://projects.spring.io/spring-data-jpa/ there are some really good examples that will make all your CRUD operations a breeze. – Ahmed Musallam Dec 24 '15 at 09:55
  • Possible duplicate of [JPA: update only specific fields](http://stackoverflow.com/questions/27818334/jpa-update-only-specific-fields) – Vivek Singh Dec 24 '15 at 10:46

2 Answers2

2

@DynamicUpdate will not solve your problem. This annotation is just for performance optimization.

If you want to update only certain properties of the entity, following are some ways:

  1. write a native sql query to update those columns(fields). (not recommended as it is better to reuse your mapping in entity wherever possible).

  2. fetch the entity first from database and then update the fields you want to and save. not recommended in general because of unnecessary code in this situation. why do we have to fetch the entity manually when there is no need here. but if there are different apis which update only one field say update1 api updates field1, update2 api updates field2, update3 updates field3,.... updateN api updates fieldN, this approach would be better(in terms of maintaining code) than the next one as next one requires several different update queries. But such needs are very rare and would not recommend this solution.

  3. use HQL. something like "update MyClass mc set mc.prop1=:prop1parameter where mc.id=:idparameter" and set parameters appropriately. (recommended)

prem kumar
  • 5,641
  • 3
  • 24
  • 36
  • in the third suggestion is it necessary that `MyClass` has getter/setter method. Does HQL use getter/setter method for update? – Abdul Samad Feb 28 '19 at 11:15
-2

you can use @DynamicUpdate annotation in order to do so on the pojo class. This only updates the required fields

sample:

@Entity
@DynamicUpdate//Add this annotation for updating selected fields
public class MyClass{
   @Id
   @GeneratedValue
   protected Long id;
   protected String prop1;

   protected String prop2;

   /*
    *  Getters And Setters
    */

}    
Vivek Singh
  • 2,047
  • 11
  • 24
  • required fields? Which are fields required? – Morteza Malvandi Dec 24 '15 at 09:01
  • I meant to say that only the respective fields which you are updating – Vivek Singh Dec 24 '15 at 09:02
  • what is the issue or case you are facing right now. – Vivek Singh Dec 24 '15 at 09:16
  • I set only `prop1` and it does not hold `prop2` value in update operation. – Morteza Malvandi Dec 24 '15 at 09:18
  • First thing, you need to keep all the values in the request body while sending it to server. If any field is missing would be considered as a change and would be considered for updation – Vivek Singh Dec 24 '15 at 09:21
  • I don't want to keep all the values in the request body. Every field that does not set, don't change it. – Morteza Malvandi Dec 24 '15 at 09:27
  • So in that case keep the primary key and the changed value while sending from client, the at the server end fetch the object from DB using the primary key and then set the value to that object and update it. – Vivek Singh Dec 24 '15 at 09:32
  • There is no other way? I have several entity and I have to implement this for all of them? – Morteza Malvandi Dec 24 '15 at 09:33
  • I can possibly say for this way only. I can;t think of any other way – Vivek Singh Dec 24 '15 at 09:40
  • even if you use dynamic update it wont solve the problem. entity has id, prop1,prop2 and all are non null values in db. now while updating you set only id and prop1 as you want only prop1 to be updated. now what hibernate does when entity with dynamic update is it fires a select query, compares to our modified entity and will update all changed values. as per our assumption prop1, prop2 were non null in db. but while updating we are setting only id(pk ) and prop1. prop3 will be null. hibernate detects all props have changed. therefore it will update prop2 with null which is not desired. – prem kumar Dec 24 '15 at 10:20
  • Yes from my last answer use the primary key and fetch the data from db first so that you don't have null property set and then update the changed data in the fetched object and then update – Vivek Singh Dec 24 '15 at 10:31