JPA之生命周期管理(二)

1 JPA状态转换图





要理解JPA的核心接口,这个图必须牢记。
分为4种状态:
1)New状态:未有id,未与Persistence Context建立关联关系。
2)Managed状态:有id,已经与Persistence Context建立了关联关系。
3)Detached状态,有id,但未与Persistence Context建立关联关系。
4)Removed状态,有id,与Persistence Context仍有关联关系,但是正准备从数据库中删除。

区分New和Detached状态:
也就是说如果你Course course = new Course();course.setName("New state");就处于New状态。
如果Course course = new Course();course.setId(1);couse.setName("Detached state");就处于Detached状态。

New状态也可以执行merge()方法,会生成一个insert 语句,并且会生成一个新的对象。
Detached状态的执行merge()方法,也会生成一个新的对象,并且视对应的id在数据库中存不存在来决定执行insert操作(不存在时)还是执行update操作(存在时)。

对比一下Hibernate的3种状态:




JPA跟Hibernate很相似,只是多了Removed状态,接口更简洁一些。


2 具体例子
各种状态对应的测试方法,见方法注释。
JpaUtil 及配置文件的代码参见:《JPA之HelloWorld(一)》

public class JpaStateMain {
    private static EntityManager em ;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        em = JpaUtil.currentManager();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        JpaUtil.closeManager();
    }

    @Before
    public void setUp() throws Exception {

    }

    @After
    public void tearDown() throws Exception {

    }

    /**
     * new状态执行persist,转换成managed状态,执行insert
     */
    @Test
    public void persist1() {
        em.getTransaction().begin();
        Course course = new Course();
        course.setName("english");
        try {
            em.persist(course); //对应hibernate session.save(course);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * detached状态执行persist,抛异常 javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persis
     */
    @Test
    public void persist2() {
        em.getTransaction().begin();
        Course course = new Course();
        course.setId(40);
        course.setName("english");
        try {
            em.persist(course);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * persist状态执行persist,不起作用
     */
    @Test
    public void persist3() {
        em.getTransaction().begin();
        Course course = new Course();
//        course.setId(40);
        course.setName("persist3");
        try {
            em.persist(course);
            em.persist(course);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * persist状态执行persist,不起作用
     */
    @Test
    public void persist4() {
        em.getTransaction().begin();
        Course course = em.getReference(Course.class,40);
//        course.setId(40);
        course.setName("persist4");
        try {
            em.persist(course);//执不执行结果都一样
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * remove状态执行persist,抛异常org.hibernate.AssertionFailure: Unable to perform un-delete for instance
     */
    @Test
    public void persist5() {
        em.getTransaction().begin();
        Course course = em.getReference(Course.class,41);
        course.setName("persist5");
        try {
            em.remove(course);
            em.persist(course);
//            course.setName("afterremove");
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * getReference获取的对象处于managed状态
     */
    @Test
    public void getReference() {
        em.getTransaction().begin();
        Course course = em.getReference(Course.class,44);
        course.setName("getrefernce");
        try {
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * find获取的对象也处于managed状态
     */
    @Test
    public void find() {
        em.getTransaction().begin();
        Course course = em.find(Course.class,45);
        course.setName("find");
        try {
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * new状态的执行remove,什么都不执行。
     */
    @Test
    public void remove1() {
        Course course = new Course();
        course.setName("remove");
        em.getTransaction().begin();
        try {
            em.remove(course);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * managed状态的执行remove,删除。
     */
    @Test
    public void remove2() {
        em.getTransaction().begin();
        Course course = em.find(Course.class,44);
        try {
            em.remove(course);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * detached状态的执行remove,抛异常java.lang.IllegalArgumentException: Removing a detached instance
     */
    @Test
    public void remove3() {
        Course course = new Course();
        course.setId(43);
        course.setName("remove3");
        em.getTransaction().begin();

        try {
            em.remove(course);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * remove状态的执行remove,不起作用。
     */
    @Test
    public void remove4() {
        em.getTransaction().begin();
        Course course = em.find(Course.class,43);
        try {
            em.remove(course);
            em.remove(course);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * new状态执行merge,生成一个新的对象,执行insert语句
     */
    @Test
    public void merge1() {
        Course course = new Course();
        course.setName("merge1");
        em.getTransaction().begin();
        try {
            Course course2 = em.merge(course);
            course2.setName("aftermerge");
//            course.setName("aftercourse");//没有作用
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }
    /**
     * detached状态执行merge,变为managed状态,生成一个新的对象,
     * course2.setname 起作用执行update, couse.setname不起作用,原来的course仍然处于detached状态
     *  course.setId(77);数据库中不存在记录,merge后,执行insert,id按自增生成,而不是set的77
     *  course.setId(49);数据库中存在记录,merge不执行insert,执行update,如果setname的值跟数据中也一样,则什么都不执行。
     */
    @Test
    public void merge2() {
        Course course = new Course();
        course.setId(52);
        course.setName("merge52");
        em.getTransaction().begin();
        try {
            Course course2 = em.merge(course);
//            course2.setName("aftermerge");
//            course.setName("aftercourse");
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * managed状态执行merge,状态不变。不生成新的对象。
     * course 和course2指向同一个对象
     */
    @Test
    public void merge3() {
        em.getTransaction().begin();
        Course course = em.find(Course.class,48);
        try {
            Course course2 = em.merge(course);
            course.setName("mergecourse");
            course2.setName("merge3");
            System.out.print(course == course2);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    /**
     * removed状态不允许执行merge,抛异常java.lang.IllegalArgumentException: org.hibernate.ObjectDeletedException: deleted instance passed to merge:
     */
    @Test
    public void merge4() {
        em.getTransaction().begin();
        Course course = em.find(Course.class,48);
        try {
            em.remove(course);
            em.merge(course);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

}



猜你喜欢

转载自frank1234.iteye.com/blog/2192637