分2种情况
情况1:当实体正在被容器管理时,你可以调用实体的set方法对数据进行修改,在容器决定flush时(这个由Container自行判断),更新的数据 才会同步到数据库,而不是在调用了set方法对数据进行修改后马上同步到数据库。如果你希望修改后的数据马上同步到数据库,你可以调用 EntityManager.flush()方法。
public void updatePerson() {
try {
Person person = em.find(Person.class, 1);
person.setName("lihuoming"); //方法执行完后即可更新数据
} catch (Exception e) {
e.printStackTrace();
}
}

    情况2:在实体Bean已经脱离了EntityManager的管理时,你调用实体的set方法对数据进行修改是无法同步更改到数据库的。你必须调用 EntityManager.merge()方法。调用之后,在容器决定flush时(这个由container自行判断),更新的数据才会同步到数据 库。如果你希望修改后的数据马上同步到数据库,你可以调用EntityManager.flush()方法。
   
public boolean updatePerson(Person person) {
try {
em.merge(person);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}

下面的代码会调用上面的方法。因为下面的第二行代码把实体Bean 返回到了客户端,这时的实体Bean已经脱离了容器的管理,在客户端对实体Bean进行修改,最后把他返回给EJB 容器进行更新操作:

PersonDAO persondao = (PersonDAO) ctx.lookup("PersonDAOBean/remote");
Person person = persondao.getPersonByID(1); //此时的person 已经脱离容器的管理
person.setName("张小艳");
persondao.updatePerson(person);

执行em.merge(person)方法时,容器的工作规则:
1>     如果此时容器中已经存在一个受容器管理的具有相同ID的person实例,容器将会把参数person的内容拷贝进这个受管理的实例,merge()方法 返回受管理的实例,但参数person仍然是分离的不受管理的。容器在决定Flush时把实例同步到数据库中。

2>容器中不存在具有相同ID的person实例。容器根据传进的person参数Copy出一个受容器管理的person实例,同时 merge()方法会返回出这个受管理的实例,但参数person仍然是分离的不受管理的。容器在决定Flush时把实例同步到数据库中。


如果传递进merge ()方法的参数不是实体Bean,会引发一个IllegalArgumentException。

merge的作用是:新new一个对象,如果该对象设置了ID,则这个对象就当作游离态处理:

    当ID在数据库中不能找到时,用update的话肯定会报异常,然而用merge的话,就会insert。

    当ID在数据库中能找到的时候,update与merge的执行效果都是更新数据,发出update语句;

     如果没有设置ID的话,则这个对象就当作瞬态处理:

     用update的话,由于没有ID,所以会报异常,merge此时则会保存数据,根据ID生产策略生成一条数据;


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐