Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to update some fields of a detached object on Hibernate?

I was wondering what's the best way to update some fields of a dettached object using HB on Java. Specially when the object has child objects attributes. For Example (annotations removed and fields number reduced to reduce noise):

public class Parent {
   int id;
   String field2;
   ...
   Child child;
}

public class Child {
   int id;
   String field3;
} 

When updating a Parent in a MVC webapp I could call for a parent instance using Session.get(Parent.class,123), use it to populate a form and display it. No DTOs, just the dettached parent is passed to the view and binded to a form. Now, I only want to allow the user to update the field2 attribute of the parent. So when the user posts the form I get a Parent instance with the id and field2 filled (I think the mvc framework dont matter here, all behaves mostly the same when binding).
Now, which strategy is the best to perform the update of the entity? I can think in few alternatives but I want to hear the experts :) (Remember that I dont want to loose the relationship between the parent and the child instances)

A) Retrive the Parent instance from the Session again and replace by hand the updated fields

Parent pojoParent; //binded with the data of the Form.
Parent entity = Session.get(Parent.class,pojoParent.getId());
entity.setField2(pojoParent.getField2()).          

I'm using this a lot. But the pojoParent seems to be used as an undercover DTO. Also it gets awful if the number of fields to update gets bigger.

B) Store the Child somewhere (httpSession?) and associate it latter.

Parent parent = Session.get(Parent.class,123);
//bind the retrieved parent to the form
// store the Child from parent.getChild() on the httpSession
...
//when the users submits the form...
pojoParent.setChild(someHttpSessionContext.getAttribute('Child'))
Session.save(pojoParent);

I think this is crap but I saw it in some projects...

C) Set the relation between Parent and Child as inmutable. Using updatable=false on the relationship I can update any parent field without worrying about loosing the child. Anyway, this is quite restrictive and the relationship never will be updated.

So, what do you think is the best way to solve this situation?

Thank you in advance!

like image 505
Mauricio Avatar asked Jan 18 '10 20:01

Mauricio


1 Answers

After loading a Parent object, you said

Now, I only want to allow the user to update the field2 attribute of the parent

Based on Use case, you can use a UpdateableParent object

public class UpdateableParent {

   private String field2;

   // getter's and setter's

}

Now our Parent repository

@Repository
public class ParentRepositoryImpl implements ParentRepository {

    @Autowired
    private SessionFactory sessionFactory;


    public void updateSpecificUseCase(UpdateableParent updateableParentObject) {

        Parent parent = sessionFactory.getCurrentSession().load(Parent.class, updateableParentObject.getId());

        try {
            // jakarta commons takes care of copying Updateable Parent object to Parent object

            BeanUtils.copyProperties(parent, updateableParentObject);
        } catch (Exception e) {
            throw new IllegalStateException("Error occured when updating a Parent object", e);
        }

    }

}

Its advantages

  • It is safe: you just update what you really want
  • You do not have to worry about MVC framework (Some MVC framework allows you set up a allowedFields property). What happens if you forget some allowed fields ???

Although it is not a Technology-related question, Seam framework allows you update only what you want. So you do not have to worry about what pattern to use.

regards,

like image 123
Arthur Ronald Avatar answered Nov 15 '22 23:11

Arthur Ronald