2

I am trying to update an entity, but when I call EntityManager.merge(), it is updating all the columns of the table. But my requirement is to update only those column which are modified. I searched on the Internet and stack overflow and the solution I got is to use @SelectBeforeUpdate and @DynamicUpdate. I tried with these annotation, but its not working. When I tried to update some specific column, all other columns are also updated.

Entity

@Entity
@SelectBeforeUpdate(value=true)
@DynamicUpdate(value=true)
@DynamicInsert(value=true)
@Table(name="Employee")
public class Employee implements Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private int ID;

    @Column(name="_first_name")
    private String firstName;

    @Column(name="_last_name")
    private String lastName;

    @Column(name="_contact")
    private Long contact;

    @Column(name="_email")
    private String email;

    @Column(name="_date_birth")
    private Date dob;

    @Column(name="_joining_date")
    private Date doj;

    @Column(name="_salary")
    private Integer Salary;
}

DAO

    logger.debug("Update method dao :");
    logger.debug(manager.getTransaction());
    Employee emp = form.getEmployee();
    logger.debug(emp);
    manager.find(Employee.class,emp.getID());
    manager.merge(emp);

In debugging it is updating all the columns

Armenak
  • 31
  • 1
  • 8
Darren
  • 23
  • 1
  • 4

1 Answers1

0

In my knowledge it is not possible in easy way, I faced this problem a years ago, the solution is accurate, but the only problem is performance(I doubt). First of all you are doing little mistake in your dao part you have to use new Employee object when the EntityManager find any by ID i.e.

Employee employee = manager.find(Employee.class,emp.getID());

And remember you have to check and merge this employee object not emp.

Now the solution is to check both the Employee object's (i.e. emp and employee) field/property value with each other and if employee field value does not matched then change its field value and the merge it. You can use java reflection for this here is the code

logger.debug("Update method dao :");
Employee emp = form.getEmployee();
Employee employee = manager.find(Employee.class, emp.getID());

Field[] empField = emp.getClass().getDeclaredFields();
Field[] employeeField = employee.getClass().getDeclaredFields();

for (int i = 0; i < empField.length; i++) {
 empField[i].setAccessible(true);
 employeeField[i].setAccessible(true);

 try {
  if (empField[i].get(emp) != null && !empField[i].get(emp).equals(employeeField[i].get(employee))) {
   employeeField[i].set(employee, empField[i].get(emp));
  }
 } catch (IllegalArgumentException e) {
  e.printStackTrace();
 } catch (IllegalAccessException e) {
  e.printStackTrace();
 }

}

employee.setUser(form.getUser());
manager.merge(employee);
manager.flush();
}

Hope this will help!

4b0
  • 21,981
  • 30
  • 95
  • 142
Vivek Singh
  • 646
  • 3
  • 10
  • 25