我是这种语言的新手。我在employee表中有一些行,bean类是Employee。我已经取了一条记录
Employee employee=this.employeeDaoImpl.getEmployeeObject(employeeId);
这是CONTROLLER
@Transactional
@RequestMapping(value="/revise_payroll")
public String revise_payroll(HttpServletRequest req,HttpServletResponse resp, Model model,RedirectAttributes redirect){
System.out.println("in revise payroll");
String employeeId=req.getParameter("employeeId");
System.out.println("E_ID for revise:"+employeeId);
List<IncrementDecrementPayrollTemp> tempPayrollList=this.employeeDaoImpl.getTemporaryPayroll(employeeId);
//get employee object from session
List<Employee> empList=this.employeeDaoImpl.getCurrentCTC(employeeId);
System.out.println("empList has: "+empList.toString());
Employee employee=this.employeeDaoImpl.getCurrentCTCasObject(employeeId);
System.out.println(("in controller employee hashcode: "+employee.toString()));
int count=0;
// this will run for only one time
for(IncrementDecrementPayrollTemp tempPayroll:tempPayrollList){
employee.setCtc(tempPayroll.getCtct());
employee.setBasicMonthly(tempPayroll.getBasicMonthlyt());
employee.setBasicAnnual(tempPayroll.getBasicAnnualt());
employee.setDaMonthly(tempPayroll.getDaMonthlyt());
employee.setDaAnnual(tempPayroll.getDaAnnualt());
employee.setHouserentMonthly(tempPayroll.getHouserentMonthlyt());
employee.setHouserentAnnual(tempPayroll.getHouserentAnnualt());
employee.setConveyanceMonthly(tempPayroll.getConveyanceMonthlyt());
employee.setConveyanceAnnual(tempPayroll.getConveyanceAnnualt());
employee.setMedicalMonthly(tempPayroll.getMedicalMonthlyt());
employee.setMedicalAnnual(tempPayroll.getMedicalAnnualt());
employee.setSpecialMonthly(tempPayroll.getSpecialMonthlyt());
employee.setSpecialAnnual(tempPayroll.getSpecialAnnualt());
employee.setPfMonthly(tempPayroll.getPfMonthlyt());
employee.setPfAnnual(tempPayroll.getPfAnnualt());
employee.setEsiMonthly(tempPayroll.getEsiMonthlyt());
employee.setEsiAnnual(tempPayroll.getEsiAnnualt());
employee.setMonthlySalary(tempPayroll.getMonthlySalaryt());
}
return new ModelAndView ("IncrementDecrementStatus");
}
现在,当我只是在employee对象上调用setter方法时,它会在控制器本身中更新sql记录。我还没有使用session.save或任何更新函数进入DAO层。
这是DAO Layer
Session session=this.sessionFactory.getCurrentSession();
String p=employeeId.trim();
String hql="From Employee e where e.employeeId=?";
Query query=session.createQuery(hql);
query.setString(0, p);
List<Employee> employeeList=(List<Employee>)query.list();
System.out.println("dao list has "+employeeList.toString());
// to update the existing records
for(Employee emp:employeeList){
int id=emp.getId();
System.out.println("id got: "+id);
Employee empl=(Employee) session.get(Employee.class, id);
String version=empl.getVersion();
System.out.println("version is: "+version);
int intVersion=Integer.valueOf(version);
intVersion=intVersion+1;
version=String.valueOf(intVersion);
empl.setVersion(version);
System.out.println("version and ctc in empl is: "+empl.getVersion()+" , "+empl.getCtc());
System.out.println("hash code in loop: "+empl.toString());
session.update(empl);
}
// this is to save new record
Integer i=(Integer)session.save(sessionEmployee);
System.out.println("save returned: "+i.toString());
}
我想要实现的目标是,我想更新已存在于sql表中的现有记录,然后使用一组新值保存employee对象作为新记录。请建议我哪里错了。谢谢!
答案 0 :(得分:10)
让我告诉你实体的生命周期状态,它可以让你更清楚这种行为。
实体可以存在三种状态 - Transient,Persistent和Detached。
Transient - 创建对象但不将其与Hibernate会话关联时,它处于Transient状态。使用setter方法对此类对象的任何修改都不能反映数据库中的更改。
持久 - 此处对象附加到Hibernate会话。所以现在Hibernate会话管理这个对象。对此对象所做的任何更改都会反映在数据库中。因为Hibernate以这样的方式设计它,如果对Persistent对象进行任何修改,它会在刷新会话时自动在数据库中更新。 (这是Hibernate的能力)。
分离 - 此状态类似于Transient。唯一的区别是处于分离状态的对象先前在会话中(即处于持久状态)。但是现在这已经不在会话中了,因为会话关闭或者调用了evict(Object)会话方法。
因此,一旦从数据库加载了对象,该对象就与会话相关联,因此处于持久状态。由于此对象处于持久状态,并且您对Persistent对象进行了更改,因此更改将反映回数据库。
根据您的要求,(将问题分成几部分)
您想从表格中获取现有记录 - 使用Employee empl=(Employee) session.get(Employee.class, id);
现在您要对此对象进行更改,但不对数据库进行更改。因此,使用session.evict(empl);
将对象置于分离状态。然后,您可以对分离的empl对象进行修改。
现在您要将这组新值保存为新记录。因此,请务必更改&#34; id&#34; empl对象的属性,因为您不能违反id值的唯一约束。您不能在表格中拥有两个具有相同ID值的记录。
不要忘记提交交易。
答案 1 :(得分:3)
这是正常行为。如果您加载实体并在EntityManager
仍然管理实体时进行修改,它会将所有更改传播回数据库。
您可以使用evict(employee)
使bean不受管理。
答案 2 :(得分:0)
Chang在任何附加实体上执行,hibernate自动检测并提交到DB。要么你可以通过evict(实体)分离加载的实体,要么通过克隆附加的实体来创建瞬态实体,以便在你的代码中进一步使用它。