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则会认为对象相同,可以交互。

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

EJB3 EntityBean中EntityManager的管理类型的更多相关文章

  1. .NET Core中的认证管理解析

    .NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...

  2. [转].NET Core中的认证管理解析

    本文转自:http://www.cnblogs.com/durow/p/5783089.html 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用 ...

  3. C++中的内存管理

    在C++中也是少不了对内存的管理,在C++中只要有new的地方,在写代码的时候都要想着delete. new分配的时堆内存,在函数结束的时候不会自动释放,如果不delete我分配的堆内存,则会造成内存 ...

  4. Oracle中Blob和Clob类型的区别与操作

    Oracle中Blob和Clob类型 1.Oracle中Blob和Clob类型的区别 BLOB和CLOB都是大字段类型,BLOB是按二进制来存储的,而CLOB是可以直接存储文字的.其实两个是可以互换的 ...

  5. linux驱动程序之电源管理之新版linux系统设备架构中关于电源管理方式的变更

    新版linux系统设备架构中关于电源管理方式的变更 based on linux-2.6.32 一.设备模型各数据结构中电源管理的部分 linux的设备模型通过诸多结构体来联合描述,如struct d ...

  6. Windows编程中的堆管理(过于底层,一般不用关心)

    摘要: 本文主要对Windows内存管理中的堆管理技术进行讨论,并简要介绍了堆的创建.内存块的分配与再分配.堆的撤销以及new和delete操作符的使用等内容. 关键词: 堆:堆管理 1 引言 在大多 ...

  7. 如何在C++中获得完整的类型名称(RTTI的typeid在不同平台下有不同的输出值表达,自建类改进了RTTI丢失的信息)

    Wrote by mutouyun. (http://darkc.at/cxx-get-the-name-of-the-given-type/)   地球人都知道C++里有一个typeid操作符可以用 ...

  8. 怎样在C++中获得完整的类型名称

    Wrote by mutouyun. (http://darkc.at/cxx-get-the-name-of-the-given-type/) 地球人都知道C++里有一个typeid操作符能够用来获 ...

  9. JNI中的内存管理(转)

    源:JNI中的内存管理 JNI 编程简介 JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互 ...

随机推荐

  1. [转载][翻译]Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[2]

    Golang作为一个略古怪而新的语言,有自己一套特色和哲学.从其他语言转来的开发者在刚接触到的时候往往大吃苦头,我也不例外.这篇文章很细致地介绍了Golang的一些常见坑点,读完全篇中枪好多次.故将其 ...

  2. BZOJ 1011 [HNOI2008]遥远的行星 (误差分析)

    1011: [HNOI2008]遥远的行星 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 4974  Solved ...

  3. (网络流 匹配 KM) Going Home --poj -- 2195

    链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82835#problem/D 有n个人有n栋房子,每栋房子里能进一个人,但每走一格 ...

  4. 基于Verilog HDL的二进制转BCD码实现

    在项目设计中,经常需要显示一些数值,比如温湿度,时间等等.在数字电路中数据都是用二进制的形式存储,要想显示就需要进行转换,对于一个两位的数值,对10取除可以得到其十位的数值,对10取余可以得到个位的数 ...

  5. hdu 2063 匈牙利算法

    http://acm.hdu.edu.cn/showproblem.php?pid=2063 男女配对最大数 匈牙利算法模板 #include <cstdio> #include < ...

  6. Immutable Collections(3)Immutable List实现原理(中)变化中的不变

    Immutable  Collections(3)Immutable List实现原理(中)变化中的不变 文/玄魂 前言 在上一篇文章(Immutable Collections(2)Immutabl ...

  7. 使用hadoop-daemon.sh 启动bootstrapStandby nameNode异常

    使用hadoop-daemon.sh 启动bootstrapStandby nameNode异常 启动bootstrapStandby nameNode时,直接通过ssh 过去执行该命令,一直无法成功 ...

  8. 【Kindeditor编辑器】 文件上传、空间管理

    包括图片上传.文件上传.Flash上传.多媒体上传.空间管理(图片空间.文件空间等等) 一.编辑器相关参数 二.简单的封装类 这里只是做了简单的封装,欢迎大家指点改正. public class Ki ...

  9. SignalR 设计理念(二)

    SignalR 设计理念(二) 实现客户端和服务器端的实时通讯. 前言: 客户端方法忽略大小写,主要原因基于是URL对大小写不敏感的问题,开发者之间为了更好的协同开发,定下的开发者协议. 问题阐述 客 ...

  10. 批处理系列(13) -从视频导出高质量GIF图片

    需要ffmpeg,配置ffmpeg到环境变量. 保存代码到HQGIF.bat,与视频同目录,管理员权限运行CMDcd到此目标目录: HQGIF.bat input_video_name.mp4 out ...