我正在尝试更新实体,但是当我调用EntityManager.merge()时,它正在更新表的所有列。但我的要求是只更新那些被修改的列。我在互联网上搜索并堆栈溢出,我得到的解决方案是使用@SelectBeforeUpdate和@DynamicUpdate。我尝试了这些注释,但它不起作用。当我尝试更新某个特定列时,所有其他列也会更新。
实体
@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);
在调试中,它正在更新所有列
答案 0 :(得分:0)
据我所知,不可能以简单的方式,我在一年前遇到这个问题,解决方案是准确的,但唯一的问题是性能(我怀疑)。 首先,你在dao部分中犯了一个小错误,当EntityManager通过ID找到任何一个时,你必须使用新的Employee对象,即
Employee employee = manager.find(Employee.class,emp.getID());
请记住,您必须检查并合并此员工对象而不是emp。
现在的解决方案是检查Employee对象(即emp和employee)的字段/属性值,如果employee字段值不匹配,则更改其字段值并合并它。您可以使用java反射,这里是代码
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();
}
希望这会有所帮助!