学习EJB3.0

1.为了存取那些服务对象,你需要通过服务器的JNDI 来查
找存根对象(session bean)或消息队列(MDB)。JNDI查找是把客户端与实际的服务端实现解藕的关键步骤。但
是,直接使用一个字符串来进行JNDI查找并不优雅。有这样几个原因:
·客户端与服务端必须有一致的基于字符串的名字。它没有在编译时得到认证或在部署时得到检查。
·从JNDI返回的服务对象的类型没有在编译时进行检查,有可能在运行时出现转换(casting)错误。
·冗长的查找代码,有着自己的try-catch代码块,在应用之间是重复的和杂乱的
EJB 3.0,对任何POJO,提供了一个简单的和优雅的方法来解藕服务对象和资源。使用@EJB注释,你可以将EJB
存根对象注入到任何EJB 3.0容器管理的POJO 中。如果注释用在一个属性变量上,容器将会在它被第一次访问
之前赋值给它。依赖注入只工作在本地命名服务中,因此你不能注入远程服务器的对象。

2.消息驱动Bean(MDB)是设计用来专门处理基于消息请求的组件。一个MDB类必须实现MessageListener 接口。当
容器检测到bean守候的队列一条消息时,就调用onMessage()方法,将消息作为参数传入。MDB在OnMessage()
中决定如何处理该消息。你可以用注释来配置MDB 监听哪一条队列。当MDB 部署时,容器将会用到其中的注
释信息。
当一个业务执行的时间很长,而执行结果无需实时向用户反馈时,很适合使用消息驱动Bean。如订单成功后给用
户发送一封电子邮件或发送一条短信等。下面的例子在用户下订单完成后,打印一份配送单。好让配送员根据地
址把商品送到客人手中。

3. 小提示:如果你的表已经存在,并且想保留数据,发布实体bean时可以把hibernate.hbm2ddl.auto的值设为none或
update,以后为了实体bean 的改动能反应到数据表,建议使用update,这样实体Bean添加一个属性时能同时在数
据表增加相应字段。

4. 实体Bean 发布前的准备工作
(1) 配置数据源并放置在[jboss 安装目录]/server/all/deploy 目录,把数据库驱动Jar 包放置在[Jboss 安装目
录]/server/all/lib 目录下,放置后需要重启Jboss服务器。如果数据源已经存在就不需要配置。
(2) 配置persistence.xml文件,在文件中指定使用的源据源及各项参数。
(3) 把实体类和persistence.xml文件打成Jar,persistence.xml 放在jar 文件的META-INF目录。

5. EntityManager 是由EJB容器自动地管理和配置的,不需要用户
自己创建,他用作操作实体Bean。

6. 在类中不用对EntityManager em进行赋值,后面却可以直接使用他。这是因为在实体Bean加载
时,容器通过@PersistenceContext注释动态注入EntityManager 对象。
如果persistence.xml文件中配置了多个不同的持久化内容。你需要指定持久化名称注入EntityManager 对象,可以
通过@PersistenceContext注释的unitName属性进行指定。如果只有一个持久化内容配置,不需要明确指定。

7. 发布在JBOSS 中的WEB应用调用EJB
有些调用EJB 的WEB 应用是直接发布在Jboss 集成环境下,本教程的客户端调用例子就是发布在Jboss 中。在
Jboss下发布WEB应用,需要把WEB应用打包成war 文件。另外在此环境下调用EJB不需要把EJB的接口类放
入/WEB-INF/classes/目录中,否则调用Stateful Bean 就会发生类型冲突,引发下面的例外。
java.lang.ClassCastException: $Proxy84
org.apache.jsp.StatefulBeanTest_jsp._jspService(org.apache.jsp.StatefulBeanTest_jsp:55)
注意:在此环境下,EJB的Local或Remote接口都可以被调用。

8. EntityManager 是用来对实体Bean进行操作的辅助类。他可以用来产生/删除持久化的实体Bean,通过主键查找
实体bean,也可以通过EJB3 QL语言查找满足条件的实体Bean。实体Bean被EntityManager管理时,EntityManager
跟踪他的状态改变,在任何决定更新实体Bean的时候便会把发生改变的值同步到数据库中。当实体Bean从
EntityManager 分离后,他是不受管理的,EntityManager 无法跟踪他的任何状态改变。
当在数据库中没有找到记录时,getReference()和find()是有区别的,find()方法会返回null,而getReference()方法
会抛出javax.persistence.EntityNotFoundException例外,另外getReference()方法不保证实体Bean已被初始化。
如果传递进getReference()或find()方法的参数不是实体Bean,都会引发IllegalArgumentException例外。

9. 更新Merge()
    通过merge (person)方法可以把Entity Bean更新到数据库。Entity Bean的状态有两种情况。
第一种:Entity Bean仍然受EntityManager 管理。
第二种:Entity Bean已经脱离了EntityManager 的管理。这种情况的出现一般是把实体Bean返回到了客户端,在客户端对实体Bean作了修改后把他返回给EJB接口进行更新操作。
    执行updatePerson(person)方法的时候,如果此时容器中已经存在一个受EntityManager 管
理的具有相同ID 的person实例,容器将会把传进的person参数的内容拷贝进这个受管理的实例。merge()方法会
返回这个受管理的实例,但传进updatePerson方法的参数person仍然是分离的不受管理的。还有另外一种情况:
如果此时容器中不存在受EntityManager管理的具有相同ID的person实例,容器将会根据传进的person参数Copy
出一个受EntityManager 管理的person实例,通过这个受管理的实例进行数据库更新操作,同时merge()方法会返
回出这个受管理的实例。传进updatePerson方法的参数person仍然是分离的不受管理的。
如果传递进merge ()方法的参数不是实体Bean,会引发一个IllegalArgumentException例外。

10. 刷新实体refresh()
    如果你怀疑当前被管理的实体已经不是数据库中最新的数据,你可以通过refresh()方法刷新实体,容器会把数据
库中的新值重写进实体。这种情况一般发生在你获取了实体之后,有人更新了数据库中的记录,这时你需要得到
最新的数据。当然你再次调用find()或getReference()方法也可以得到最新数据,但这种做法并不优雅。

11.@ManyToOne注释的fetch属性默认值是FetchType.EAGER。
optional属性是定义该关联类对是否必须存在,值为false时,关联类双方都必须存在,如果关系被维护端不存在,
查询的结果为null。值为true时, 关系被维护端可以不存在,查询的结果仍然会返回关系维护端,在关系维护端
中指向关系被维护端的属性为null。optional属性的默认值是true。

12. 一个EJB3程序一般包含一个服务器端(如JBoss)和一个客户端(Tomcat或JBoss),客户端用Tomcat时,客户端与服务器端不在一个VM内,即使客户端将服务器端的工程包含了进来,也需要在客户端创建SessionBean接口,否则会出错。

你可能感兴趣的:(bean,数据库,jboss,ejb,服务器,merge)