8

I have a object A which maps to table A in DB

class A {
     Integer id;
     String field2,field2;field3 ,... fieldN;
     //lots of other attribute
}

Now i want to write a DAO api that just updates a single field.One approach is that i can first load the object then changes the attribute i need and then use merge api

//start transcation
A a = session.load(A.class, id);
A.setfieldP(newValue)
session.merge(A)
//commit transcation

Now if i use following code

 //start transcation
 A a = new A();
 a.setId(id); //set a id by which object A exists in DB
 A.setfieldP(newValue)
 session.merge(A)
 //commit transaction

Now second approach all fields except id and fieldP are set to null

1)Now is there any other approach?
2)Can i use update instead of merge ?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
akshay
  • 5,235
  • 14
  • 39
  • 49

4 Answers4

13

If you need to update lots of entities at once the most efficient way is to use a query:

Query query = session.createQuery("update EntityName set fieldP = 'newValue' "
        + "where id IN (75, 76)");
query.executeUpdate();

This allows you to change field values without loading the entity or entities into memory.

It is best practice is to use named queries and named parameters - the above implementation is just an example.

Russ Hayward
  • 5,617
  • 2
  • 25
  • 30
  • this can be considered offtopic to this question. – bluefoot Jul 22 '11 at 13:51
  • 6
    I disagree. Firstly, he asked for a different approach if there was one. Secondly, from his second code snippet it is clear that he wants to avoid loading the entity into memory. – Russ Hayward Jul 22 '11 at 14:32
2

Using JPA you can do it this way.

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaUpdate<User> criteria = builder.createCriteriaUpdate(User.class);
Root<User> root = criteria.from(User.class);
criteria.set(root.get("fname"), user.getName());
criteria.set(root.get("lname"), user.getlastName());
criteria.where(builder.equal(root.get("id"), user.getId()));
session.createQuery(criteria).executeUpdate();
Arjun Nayak
  • 1,222
  • 1
  • 13
  • 22
2

I usually prefer session.get vs session.load, as session.get will return null as opposed to throwing an exception, but it depends on the behavior you want.

loading the object, setting your field, and calling either

 session.merge(myObject)

is the standard way, although you can also use

 session.saveOrUpdate(myObject)

as long as the object hasn't been detached, which in your case, it won't have been detached. Here is a good article explaining the differences in merge and saveOrUpdate.

In your second example, you are editing the primary key of the object? This is generally bad form, you should delete and insert instead of changing the primary key.

Community
  • 1
  • 1
Paul Sanwald
  • 10,899
  • 6
  • 44
  • 59
  • You probably know this already but saveOrUpdate does work with detached objects. The only time you run into trouble with it is when there is an existing object with the same id attached to the session. – Russ Hayward Jul 22 '11 at 13:48
  • `saveOrUpdate` will update the values to an existent object in the db (+1) – bluefoot Jul 22 '11 at 13:50
  • @Russ Sanwald: In second approach whati am trying to do is , i want to update a object.Now for updating it i dont want to fetch it from db and then update, instead i am creating a new Object A , set its primary key and the fieldN and then update.I set the primary key as i want to update object with primarykey =X (assuming object with id x is already present in DB and i set fieldN as i want to update it.I am not changing the primary key but my purpose is to chnage value of fieldN of object A with Id=X – akshay Jul 22 '11 at 14:15
  • @akshay: You can update an object without loading it into memory by using an update query. See my answer. – Russ Hayward Jul 22 '11 at 14:33
  • @Russ and all: If i dont want to use quesry is my approach 1 perfectly ok? – akshay Jul 22 '11 at 14:36
  • @akshay: Yes there is nothing wrong with it. If you are only updating a single entity then it is the simplest way to go. – Russ Hayward Jul 22 '11 at 16:31
1

One more optimization here could be using dynamic-update set to true for the entity. This will make sure that whenever there is an update, only field(s) which are changed only gets updated.

sudmong
  • 2,036
  • 13
  • 12
  • is it necessary to fetch the object first from db and then update.What if i instantiate a new object with id X and then set only the fields i want to update ?In my approach 2 all other fields which are not set are stored as nulls, i want that it should preserve the old not null values – akshay Jul 22 '11 at 14:18