容器管理的EntityManager(Container-Managed EntityManager)? 通过将@PersistenceContext注解标注在EntityManager类型的字段上,这样得到的EntityManager就是容器管理的EntityManager。由于是容器管理的,所以我们不需要也不应该显式关闭注入的EntityManager实例。我的疑问是,容器管理的EntityManager是一个单例,那么在运行时候性能怎么样,会不会出现线程问题。求教

解决方案 »

  1.   

    谁告诉你EntityManager是单例的?
      

  2.   

    它只是对session的又一层包装,不要想的太复杂了
      

  3.   

    Hibernate 的 JPA 实现可能是对 Hibernate 的 Session 再包装了一下,不过其他的 JPA 实现就不是了,比如:OpenJPA, EclipseLink 等等。EntityManager 并不是单实例的,每调用一次由 EntityManagerFactory 创建一个 EntityManager 对象。用完之后就关闭扔掉,或者是还回到池中去了。
      

  4.   

    我测试过,不同的对象每次注入的都是同一个EntityManager,它不是单例是什么,
    @PersistenceContext注解标注在EntityManager类型的字段,那么每次得到的都是同一个EntityManager,我打印出的对象哈希码也是一样的。请大家指教
      

  5.   

    回二楼的,没人告诉我EntityManager是单例,可是由Spring管理的实体,默认就是单例。
      

  6.   

    Spring 管理的是 EntityManagerFactory,并不是管理的 EntityManager,因为你的 EntityManager 会被具体的 JPA 实现进行池化处理以提高数据库连接性能,EntityManager 会被重用,因此你看到的是同一个对象其实也是很正常的。PS:你所指的容器管理指的是 Spring,还是 EJB 容器?
      

  7.   

    谢谢7楼的回答,我指的是spring事务管理,经过你的解答我明白了,虽然是同一个对象,但是经过连接池的处理,这样提高并发性,但也不影响事务,如果这里不是同一个对象,那么spring对jpa的事务就不好管理。
      

  8.   

    那么Spring对jdbc的事务管理,对hibernate的事务管理都是一个道理了,应该也是这么实现的。
      

  9.   


    默认是默认。
    容器对于@PersistenceContext注解,跟普通的@Resource注入注解的处理是不同的。
    至于为什么出现你测试的那种情况7楼解释了,楼主可以模拟大并发量的请求测试可能答案就不一样了。
    如果说Hibernate == JPA,那么SessionFactory == EntityManagerFactory,Session == EntityManager
      

  10.   

    恩,回楼上的,我对spring这些框架之类的也是刚接触,希望能说明白点。
      

  11.   

    这句话不是太明白你的意思。。spring要保证的是同一次请求里所有对数据库操作用的是同一个EntityManager才好进行JDBC事务管理。事务管理管理的是JDBC的Connection,spring只要保证同一次请求的所有用到的数据库连接是同一个Connection,那么就能用jdbc事务管理,否则需要用JTA才行。
      

  12.   

    我说的是spring对jdbc事务的管理,spring对hibernate的管理,因为我在学习,这三种事务的管理都要接触,但是对于他们注入的都是同一个对象不了解,spring对jdbc的注入是jdbctemplate,对hibernate是hibernatetemplate,对jpa的注入是entitymanager,经过7楼的点拨,我好像明白了,虽然注入的是同一个对象,但是请求过来获得的链接却是不同的,这样既保证了并发性,又保证了事务的管理。