zoukankan      html  css  js  c++  java
  • EJB3 EntityBean中EntityManager的管理类型

    EJB中EntityManager的管理方式有两种:Container-managed EntityManager和Application-managed EntityManager

    即容器管理的EntityManager和应用管理的EntityManager

    在EJB中,EntityManager所进行的持久化的方式与Hibernate的方式是不同的。

         1.在Hibernate的同一个事务中,通过getCurrentSession获取的session对象均为同一个,保存于threadlocal中,以保证对数据的操作为同一个对象。

         2.而EJB中,以容器管理的EntityManager为例,通过注解注入后,在同一个事物中,在各个Bean中获取的EntityManager为不同的对象,但其背后所指向的        persistenceContext  为同一个,所以保证对一个对象进行操作。

    1)容器管理的EntityManager

        简单的说,就是使用注解,在程序启动的时候由容器自动注入的方式,这是一种普遍采用的方式。

    @PersistenceContext(unitName="jbossDB")
        private EntityManager em;

         在使用结束时,不需要自己关闭,有容器来管理。unitName为数据库资源的名字,有presidence.xml中定义

         在该方式下,对应两种persistence类型:

         1.transaction-scope persistence:由容器管理的persistence,其生命周期为一个transaction,这是默认的模式

            一个transaction可认为是客户端向服务器端的一个请求,从开始到结束的一个周期

         2.Extended-scope persistence:用于stateful session bean中,其生命周期随stateful的生命周期

    @PersistenceContext(unitName="jbossDB",type=PersistenceContextType.EXTENDED)
        private EntityManager em;

           其设置方式为通过PersistenceContextType来设置。

           Stateful Session Bean 和 Stateless Session Bean最大的区别就是前者会保存客户端的信息,使得同一个客户端在一个Bean中多次访问的时候均为访问同一个Bean。

           而后者则可看作单例模式,他不会保存客户端的信息,所以第二个客户端依然可以使用该Bean对象。

           实体:

    import java.io.Serializable;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Version;
    
    @Entity
    public class People implements Serializable{
    
        /**
         * 
         */
        private static final long serialVersionUID = 20151228215045281L;
        @Id
        @GeneratedValue
        private int id;
        private String name;
        private String password;
        
        @Version
        private int version;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public int getVersion() {
            return version;
        }
    
        public void setVersion(int version) {
            this.version = version;
        }
    }

           Bean继承的接口:

    import com.welv.jpa.People;
    
    public interface PeopleManager {
    
        public void addPeople(People p);
        public People getPeople(int id);
        public void setName(String name);
        public void setPassword(String password);
        
    }

           Bean的实现:

    import javax.ejb.Remote;
    import javax.ejb.Stateful;
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.PersistenceContext;
    import javax.persistence.PersistenceContextType;
    import javax.persistence.PersistenceUnit;
    
    import com.welv.ejb.PeopleManager;
    import com.welv.jpa.People;
    
    @Stateful
    @Remote
    public class PeopleManagerBean implements PeopleManager {
    
        @PersistenceContext(unitName="jbossDB",type=PersistenceContextType.EXTENDED)
        private EntityManager em;
        private People p;
        
        
        
        @Override
        public void addPeople(People p) {
            em.persist(p);
    
        }
    
        @Override
        public People getPeople(int id) {
            p = em.find(People.class, id);
            return p;
        }
    
        @Override
        public void setName(String name) {
            p.setName(name);
        }
    
        @Override
        public void setPassword(String password) {
    
            p.setPassword(password);
            
        }
    
    }

           客户端代码:

    import java.util.Properties;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import com.welv.ejb.PeopleManager;
    import com.welv.jpa.People;
    
    public class JpaEJBClient {
        public static void main(String[] arg) {
    
            try {
                final Properties jndiProperties = new Properties();
                jndiProperties.put(Context.URL_PKG_PREFIXES,
                        "org.jboss.ejb.client.naming");
                final Context context = new InitialContext(jndiProperties);
                final String appName = "";
                // 部署的jar文件的名字
                final String moduleName = "EJB_06";
                final String distinctName = "";
                // 实现类的类名
                final String beanName = "PeopleManagerBean";
                // 接口类的全名
                final String viewClassName = PeopleManager.class.getName();
    
                String lookupStr = "ejb:" + appName + "/" + moduleName + "/"
                        + distinctName + "/" + beanName + "!" + viewClassName+"?stateful";
    
                System.out.println(lookupStr);
    
                
                PeopleManager ejb = (PeopleManager) context.lookup(lookupStr);
                
    //            People p = new People();
    //            
    //            p.setName("ll");
    //            p.setPassword("123456");
    //            
    //            ejb.addPeople(p);
                People p = ejb.getPeople(1);
                
                ejb.setName("cccc");
                ejb.setPassword("1234455");
    
            } catch (Exception e) {
                System.out.println("============================================");
                e.printStackTrace();
                System.out.println("============================================");
                System.out.println("请检查调用方法是否为远程");
            }
        }
    }

           从Bean的实现中可以看出,对People对象操作的一些方法是没有加载People对象的。如果是通过Stateless将接口暴露出去,这无法实现相应方法的功能。

           a.由于使用的是StatefulBean,所以获取的Bean对象是有状态的,Stateful周期中多次的请求都是用同一个Bean,在远程使用getPeople()方法的时候,Session Bean中会

              将People对象保存在this.People对象中,所以在同一个Stateful周期中使用其他的方法对People对象进行操作时就不需要重新load People对象。

           b.若使用的是StatelessBean,则必须要在方法中重新加载,因为Stateless是不保存客户端信息的,也就是在同一个使用一个Stateless进行请求的时候,请求的Bean对象不

              是同一个,所以如果不加载对象,会有NullPointException产生。

    2)应用管理的EntityManager

        由PersistenceUnit注入EntityManagerFactory中

    @PersistenceUnit(unitName="jbossDB")
        private EntityManagerFactory emf;

         在transaction结束时需要手动将获取的EntityManager关闭(closs);

    **private static final long serialVersionUID = 20151228215045281L;作用:

        该代码的作用用于匹配,在一般情况下,若EJB中的实体对象和客户端中的对象如果一致,则可以互相传递,但如果EJB中多加了属性,则再次访问的时候则会失败,而如果两边的代码中有相同的serialVersionUID则会认为对象相同,可以交互。

    ***由于刚了解该技术点,没有理解透

  • 相关阅读:
    JMeter结构体系及运行原理
    maven pom配置文件样本
    django踩坑
    spring踩坑
    蓝牙连上电脑没声音
    XML 解析 & 特殊字符报错
    IDEA下maven工程的classpath
    mysql踩坑
    工作日记-9 远程接口调用注意点
    工作日记-8 ajax缓存
  • 原文地址:https://www.cnblogs.com/welv/p/5084329.html
Copyright © 2011-2022 走看看