`
cyj33
  • 浏览: 3353 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

第一个实体Bean实例——建立与数据库的连接

阅读更多
核心提示:从EJB的入门知识我们已经了解到,在EJB 2.x中,EJB有3种类型的Bean,分别是会话Bean(Session Bean)、消息驱动Bean(Message-Driven Bean)和实体Bean(Entity Bean)。随着EJB 3的推出,EJB中的实体Bean逐渐被JPA规范所替代,JPA不仅能在EJB环境中使用,而
从EJB的入门知识我们已经了解到,在EJB 2.x中,EJB有3种类型的Bean,分别是会话Bean(Session Bean)、消息驱动Bean(Message-Driven Bean)和实体Bean(Entity Bean)。随着EJB 3的推出,EJB中的实体Bean逐渐被JPA规范所替代,JPA不仅能在EJB环境中使用,而且能在Java SE、Java EE环境中使用,相对于EJB 2.x中的实体Bean,它的使用范围更广。但这里我们仍然将其称做实体Bean。

与会话Bean和消息驱动Bean类似,新的实体Bean也是一个加了注释符(@Entity)的简单 Java对象(POJO),实体关系和O/R映射也是通过注释符来定义的,并提供几种不同的数据库操作规范。一旦被EntityManager访问,它就成为了一个持久化对象,并且成为了持久化上下文的一部分。此时我们就可以像使用Hibernate、iBATIS一样来使用实体对象了。

接下来我们将通过本节课和后面的两节课来详细讲解实体Bean的开发技术。

Ø 第一个实体Bean实例:通过开发第一个实体Bean,建立与数据库的连接,演示实体Bean的开发与调用过程。

Ø 实体管理器:执行数据库更新的方法。

Ø 生命周期:实体Bean的监听和回调。

Ø 关系实体映射:开发实体的方法。

Ø JPQL查询语言:执行数据库实体查询。

Ø 原生SQL查询:执行原生SQL语句。

它们之间的关系如图6-1所示,通过实体管理器操作实体Bean,来实现对数据库的更新、JPQL查询和原生SQL查询。实体管理器是工具,实体Bean是数据。



图6-1  实体Bean内容结构图

本节课将重点讲解前3个部分的内容,即:

Ø 建立与数据库的连接。

Ø 实体管理器。

Ø 实体Bean的生命周期。

通过本节课的学习,你将能够通过实体Bean的开发,实现对数据库的操作。

6.1  第一个实体Bean实例——建立与数据库的连接
下面首先来讲解实体Bean的调用过程,然后通过开发第一个实体Bean,演示该配置与开发的过程,包括以下内容:

Ø 配置数据源。

Ø 指定数据源。

Ø 开发第一个实体Bean——Student.java。

Ø 开发会话Bean进行调用——StudentDAORemote.java和StudentDAO.java。

Ø 打包并部署到JBoss服务器。

Ø 开发客户端进行测试——StudentDAOClient.java。

通过本节的学习,你将能够通过实体Bean的建立与MySQL数据库的连接,往数据表中插入一条记录。

6.1.1  实体Bean的工作原理
我们知道,实体Bean是作为持久化类被EJB容器管理的,要实现对该持久化类的调用,必须经过以下步骤。

(1)配置数据源连接。

(2)在配置文件persistence.xml中指定数据源。

(3)开发实体Bean。

(4)在会话Bean、Java SE或Java EE中调用实体Bean。

如图6-2所示。

实体Bean不仅可以被会话Bean调用,还可以被任何的Java类、JSP和Servlet调用,调用的目的是实现对数据库的操作。它的意义与Hibernate、iBATIS完全相同,就是作为系统的DAO层,实现对数据库的访问。

下面我们就按照从底层到上层的顺序,来演示创建与数据库的连接的过程。

6.1.2  配置数据源
JBoss有一个默认的数据源DefaultDS,它使用JBoss内置的HSQLDB数据库。其数据源对应的配置文件为D:\jboss-5.0.0.GA\server\default\deploy\hsqldb-ds.xml,其中包含如下5个设置:

<jndi-name>DefaultDS</jndi-name>

<connection-url>jdbc:hsqldb:${jboss.server.data.dir}${/}hypersonic${/}localDB</connection-url>

<driver-class>org.hsqldb.jdbcDriver</driver-class>

<user-name>sa</user-name>

<password></password>

其中的意义表示如下。

Ø jndi-name:指定JNDI命名。

Ø connection-url:数据库连接URL。

Ø driver-class:数据库驱动类。

Ø user-name:数据库登录用户名。

Ø password:数据库登录密码。

我们只需要通过引用JNDI命令DefaultDS来引用该数据源,引用的方法很简单,只需要在persistence.xml中指定该别名即可(见下一节)。

在实际的应用中,我们可能需要使用不同的数据库,如MySQL、Oracle、MSSQL Server等。各种数据库的数据源配置模版可以在D:\jboss-5.0.0.GA\docs\examples\jca目录中找到,默认名称为数据库名+ -ds.xml,例如下面的例子。

Ø mysql-ds.xml:MySQL数据源配置模板。

Ø oracle-ds.xml:Oracle数据源配置模板。

Ø mssql-ds.xml:MSSQL Server数据源配置模板。

在D:\jboss-5.0.0.GA\docs\examples\jca目录下共包含38种模板,表明它支持对38种数据源的连接。

要配置到某一个数据源的连接,需要进行如下的步骤。

(1)复制添加该数据库类型的配置模板到D:\jboss-5.0.0.GA\server\default\deploy目录,并设置正确的数据源参数。

(2)添加该数据库的驱动程序包到D:\jboss-5.0.0.GA\server\default\lib目录,并重启JBoss服务器加载该程序包。

在准备篇中,我们已经安装并配置了MySQL数据库,下面我们以MySQL数据库为例,来添加到该数据库的数据源,配置步骤如下。

(1)复制D:\jboss-5.0.0.GA\docs\examples\jca\mysql-ds.xml到JBoss部署目录D:\jboss-5.0.0.GA\ server\default\deploy中,并修改配置参数如下:

<jndi-name>MySqlDS</jndi-name>

<connection-url>jdbc:mysql://localhost:3306/demo</connection-url>

<driver-class>com.mysql.jdbc.Driver</driver-class>

<user-name>root</user-name>

<password>123</password>

其中的意义表示如下。

Ø jndi-name:指定JNDI命名为MySqlDS。

Ø connection-url:指定连接本地的demo数据库。

Ø driver-class:数据库驱动类com.mysql.jdbc.Driver。

Ø user-name:数据库登录用户名为root。

Ø password:数据库登录密码为123。

如果JBoss服务器处于启动状态,则此时JBoss会自动监控到该文件,并加载进来,同时在控制台输入如下信息:

16:42:06,937 INFO  [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=

MySqlDS' to JNDI name 'java:MySqlDS'

这就表明,新配置的数据源MySqlDS生效了。如果你随时修改该文件,则JBoss服务器也能够监控到你的修改,并重新加载该数据源,在控制台输入如下信息:

16:42:27,109 INFO  [ConnectionFactoryBindingService] Unbound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=

MySqlDS' from JNDI name 'java:MySqlDS'

16:42:27,328 INFO  [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=

MySqlDS' to JNDI name 'java:MySqlDS'

(2)下载MySQL数据库的驱动。

Ø 下载页面:http://dev.mysql.com/downloads/connector/j/5.0.html。

Ø 下载文件:mysql-connector-java-5.0.8.tar.gz。

Ø 驱动包文件:mysql-connector-java-5.0.8-bin.jar。

将mysql-connector-java-5.0.8-bin.jar添加到D:\jboss-5.0.0.GA\server\default\lib目录,然后重启JBoss来加载驱动包即可。



 
  提 示

 
 
对于其他数据库,如Oracle、SQL Server等,均可以按照类似的步骤配置相应的数据源。

6.1.3  指定数据源——persistence.xml
以上配置的数据源由JBoss服务器加载和管理,要使用这些数据源,还需要在我们的应用中指定引用哪一个数据源。引用的方法很简单,只需要在应用的/ejbModule/META-INF目录下添加一个配置文件persistence.xml即可,并在该文件中指定引用的数据源JNDI名称,同时可以设置该数据源的相关操作属性。



 
  提 示

 
 
persistence.xml是一个XML文件,它的文档定义Schema可以从http://java.sun.com/xml/ ns/persistence/persistence_1_0.xsd上下载到。

下面是一个persistence.xml配置实例,代码如下所示:

程序6-1  配置文件persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>

<persistence xmlns="http://java.sun.com/xml/ns/persistence"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence

        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">

    <persistence-unit name="demo">

        <jta-data-source>java:/MySqlDS</jta-data-source>

        <properties>

            <property name="hibernate.hbm2ddl.auto" value="create-drop" />

        </properties>

    </persistence-unit>

</persistence>

其中包含3个配置元素,分别如下。

Ø persistence-unit元素:可以有一个或多个,每个persistence-unit元素定义了持久化内容名称、使用的数据源名称及Hibernate属性。其中的name属性用于设置持久化名称。

Ø jta-data-source元素:用于指定实体Bean使用的数据源名称MySqlDS,当指定数据源名称时java:/前缀不能缺少,并注意数据源名称的大小写。

Ø properties元素:用于指定Hibernate的各项属性,如果hibernate.hbm2ddl.auto的值设为create-drop,则在实体Bean发布及卸载时将自动创建及删除相应的数据库表。为了使以后实体Bean的改动能反应到数据表,建议使用update,这样实体Bean添加一个属性时能同时在数据表增加相应字段。



 
  注 意

 
 
(1)properties元素属性在各个应用服务器使用的持久化产品中都不一样,如JBoss使用Hibernate,WebLogic10使用Kodo,GlassFish/Sun Application Server/Oralce使用Toplink。

(2)properties元素的可用属性及默认值可以在下面的文件中找到:D:\jboss-5.0.0.GA\ server\all\deployers\ejb3.deployer\META-INF\persistence.properties。

(3)JBoss服务器在启动或关闭时会引发实体Bean的发布及卸载。

6.1.4  开发第一个实体Bean——Student.java
实体Bean实际上对应了数据库中的表,它是数据库中表在Java类中的表现,通常为最普通的POJO类。EJB容器能够根据实体Bean自动在数据库中创建数据表,这就需要将实体类与数据表的结构进行对应,包括表名、字段名、字段长度、字段类型、主键等信息。

为了开发一个与数据库表对应的单表实体Bean,我们首先设计一个学生表student的数据结构,该表共包括7个字段,如表6-1所示。

表6-1  学生表student
序号
字段名
字段描述
字段类型
Java类型

1
studentid
学号(主键)
int
Integer

2
name
姓名
varchar(50)
String

3
sex
性别
bit(1)
boolean

4
age
年龄
smaillint(6)
Short

5
birthday
出生日期
datetime
Date

6
address
地址
varchar(100)
String

7
telephone
电话
varchar(20)
String


其中的字段类型对应了MySQL数据库中的字段类型,Java类型为相应的POJO类中的字段类型,即实体Bean中的变量类型。

要开发一个与该表对应的实体Bean很简单,只需要新建一个POJO类,添加7个与表的字段同名的变量,同时使用一些注释符来表示该实体Bean与数据表student的对应映射关系即可。

首先在Eclipse中新建一个EJB项目“EntityBeanTest”,并创建包com.ejb.entitybean,然后在该包下新建实体Bean类Student.java。首先我们来看看这个完整的实体类的代码,如下所示:

程序6-2  实体Bean类Student.java
package com.ejb.entitybean;

import java.io.Serializable;

import java.util.Date;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.Table;

@SuppressWarnings("serial")

@Entity

@Table(name = "Student")

public class Student implements Serializable {

    private Integer studentid;       //学号

    private String name;         //姓名

    private boolean sex;              //性别

    private Short age;           //年龄

    private Date birthday;       //出生日期

    private String address;      //地址

    private String telephone         //电话

    @Id

    @GeneratedValue

    public Integer getStudentid() {

        return studentid;

    }

    public void setStudentid(Integer studentid) {

        this.studentid = studentid;

    }

    @Column(name = "name", length = 50)

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    @Column(nullable = false)

    public boolean getSex() {

        return sex;

    }

    public void setSex(boolean sex) {

        this.sex = sex;

    }

    @Column(nullable = false)

    public Short getAge() {

        return age;

    }

    public void setAge(Short age) {

        this.age = age;

    }

    public Date getBirthday() {

        return birthday;

    }

    public void setBirthday(Date birthday) {

        this.birthday = birthday;

    }

    @Column(name = "address", length = 100)

    public String getAddress() {

        return address;

    }

    public void setAddress(String address) {

        this.address = address;

    }

    @Column(name = "telephone", length = 20)

    public String getTelephone() {

        return telephone;

    }

    public void setTelephone(String telephone) {

        this.telephone = telephone;

    }

}



 
  注 意

 
 
实体Bean通常需要实现Serializable接口,这样就可以有EJB客户端创建该对象,并将该对象传送到服务端,否则将引发java.io.InvalidClassException例外。

该类是一个Java POJO类,其中包含了7个变量,并为每个变量添加了getter/setter函数。为了将该POJO类表现为一个实体Bean,添加了一些注释符,来与数据表student进行对应,这些注释如下。

Ø @Entity注释指明这是一个实体Bean,每个实体Bean类映射数据库中的一个表。

Ø @Table注释的name属性指定映射的数据表名称,Student类映射的数据表为Student。

Ø @Column注释定义了映射到列的所有属性,如列名是否唯一,是否允许为空,是否允许更新等,其属性介绍如下。

Ø  name:映射的列名。如映射Student表的name列,可以在name属性的getName()方法上面加入@Column(name = "name"),如果不指定映射列名,则容器会将属性名称作为默认的映射列名。

Ø  unique:是否唯一。

Ø  nullable:是否允许为空。

Ø  length:对于字符型列,length属性指定列的最大字符长度。

Ø  insertable:是否允许插入。

Ø  updatable:是否允许更新。

Ø  columnDefinition:定义建表时创建此列的DDL。

Ø  secondaryTable:从表名。如果此列不建在主表上(默认建在主表上),则该属性定义该列所在的从表的名字。

Ø @Lob注释指定某一个字段为大的文本字段类型。

Ø @Id注释指定studentid属性为表的主键。

Ø @GeneratedValue注释定义了标识字段的生成方式,本例中的studentid的值由MySQL数据库自动生成,它可以有以下多种生成方式。

Ø  TABLE:容器指定用底层的数据表确保唯一。

Ø  SEQUENCE:使用数据库的SEQUENCE 列来保证唯一。

Ø  IDENTITY:使用数据库的INDENTIT列来保证唯一。

Ø  AUTO:由容器挑选一个合适的方式来保证唯一。

Ø  NONE:容器不负责主键的生成,由调用程序来完成。

例如:

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

public Integer getId() {

    return this.id;

}

这样就开发完实体Bean了,它除了在POJO上添加了一些注释外,与普通的POJO类没有任何区别。

6.1.5  开发会话Bean进行调用——StudentDAORemote.java和StudentDAO.java
由实体Bean的工作原理可知,它可以被EJB的会话Bean调用,也可以被任何的Java类或JSP调用。在EJB应用程序中,我们通常会在会话Bean中调用实体Bean,来实现对数据库的操作。

下面我们来开发一个远程的会话Bean组件,通过调用实体Bean类Student.java,来实现往数据表student中插入一条记录。

首先在项目EntityBeanTest中新建一个包com.ejb.dao,然后按照会话Bean的开发方法,在该包中新建一个远程的会话Bean组件StudentDAO,新建完后会产生一个远程接口类StudentDAORemote.java和实现类 StudentDAO.java。

1)远程接口类StudentDAORemote.java该类是一个远程接口类,通过注释符@Remote进行标识。为了执行插入student功能,首先在该接口中添加一个函数insert(),用来执行插入某一个Student类型的数据。如下所示:

程序6-3  远程接口类StudentDAORemote.java
package com.ejb.dao;

import java.util.List;

import javax.ejb.Remote;

import com.ejb.entitybean.Student;

@Remote

public interface StudentDAORemote {

    public boolean insert(Student student);

}

2)实现类StudentDAO.java该类实现了远程接口StudentDAORemote.java,并通过@Stateless标识为无状态会话Bean。

首先它包含了一个EntityManager类型的变量em,EntityManager是实体管理器,顾名思义,它是实体Bean的管理容器。通过该对象,我们能够实现与数据库的各种交互,包括增、删、改、查等。

该实体变量em还通过注释@PersistenceContext来实现动态注入EntityManager对象,如果 persistence.xml文件中配置了多个不同的持久化内容,则还需要指定持久化名称注入EntityManager 对象,可以通过@PersistenceContext注释的unitName属性进行指定,例如:

@PersistenceContext(unitName="demo")

EntityManager em;

如果只有一个持久化内容配置,则不需要明确指定。

然后开发该类实现接口中的函数insert(),只需要调用em的persist()函数,就能够将Student对象持久化到数据库中,即往数据库中新增一条记录。

完整的实现代码如下:

程序6-4  实现类StudentDAO.java
package com.ejb.dao;

import java.util.List;

import javax.ejb.Stateless;

import javax.persistence.EntityManager;

import javax.persistence.PersistenceContext;

import javax.persistence.Query;

import com.ejb.entitybean.Student;

@Stateless

public class StudentDAO implements StudentDAORemote {

    @PersistenceContext

    protected EntityManager em;

    public boolean insert(Student student) {

        try {

            em.persist(student);

        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

        return true;

    }

}

6.1.6  打包并部署到JBoss服务器
完成了以上的开发,我们就可以将当前应用发布到JBoss中,形成JNDI服务供外部访问了。发布的方法很简单,只需要导出该项目的JAR包到JBoss的部署目录D:\jboss-5.0.0.GA\server\default\ deploy即可。操作的方法是:用鼠标右键单击项目EJBTest,在弹出的快捷菜单中依次选择【Export】→【EJB JAR file】命令,指定导出文件为D:\jboss-5.0.0GA\server\default\deploy \EntityBeanTest.jar,该文件被自动发布到JBoss服务器中。JBoss服务器就会自动加载该服务,并在控制台输出如下信息:

14:59:29,578 INFO  [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@20142668

        {vfszip:/D:/jboss-5.0.0.GA/server/default/deploy/EntityBeanTest.jar}

14:59:29,578 INFO  [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@20142668

        {vfszip:/D:/jboss-5.0.0.GA/server/default/deploy/EntityBeanTest.jar}

14:59:29,703 INFO  [JBossASKernel] Created KernelDeployment for: EntityBeanTest.jar

14:59:29,703 INFO  [JBossASKernel] installing bean: jboss.j2ee:jar=EntityBeanTest.jar,name=StudentDAO,service=EJB3

14:59:29,703 INFO  [JBossASKernel]   with dependencies:

14:59:29,703 INFO  [JBossASKernel]   and demands:

14:59:29,703 INFO  [JBossASKernel]   jboss.ejb:service=EJBTimerService

14:59:29,703 INFO  [JBossASKernel]   persistence.unit:unitName=#demo

14:59:29,703 INFO  [JBossASKernel]   and supplies:

14:59:29,703 INFO  [JBossASKernel]   jndi:StudentDAO/remote

14:59:29,703 INFO  [JBossASKernel]   jndi:StudentDAO/remote-com.ejb.dao.StudentDAORemote

14:59:29,703 INFO  [JBossASKernel]   Class:com.ejb.dao.StudentDAORemote

14:59:29,703 INFO  [JBossASKernel] Added bean(jboss.j2ee:jar=EntityBeanTest.jar,name=StudentDAO,service=EJB3) to

        KernelDeployment of: EntityBeanTest.jar

14:59:29,750 INFO  [PersistenceUnitDeployment] Starting persistence unit persistence.unit:unitName=#demo

14:59:29,765 WARN  [Ejb3Configuration] Persistence provider caller does not implement the EJB3 spec correctly.

        PersistenceUnitInfo.getNewTempClassLoader() is null.

14:59:29,765 INFO  [AnnotationBinder] Binding entity from annotated class: com.ejb.entitybean.Student

14:59:29,765 INFO  [EntityBinder] Bind entity com.ejb.entitybean.Student on table Student

14:59:29,812 INFO  [HibernateSearchEventListenerRegister] Unable to find org.hibernate.search.event.FullTextIndexEventListener on

        the classpath. Hibernate Search is not enabled.

14:59:29,812 INFO  [ConnectionProviderFactory] Initializing connection provider:

        org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider

14:59:29,812 INFO  [InjectedDataSourceConnectionProvider] Using provided datasource

14:59:29,812 INFO  [SettingsFactory] RDBMS: MySQL, version: 5.0.45-community-nt

14:59:29,812 INFO  [SettingsFactory] JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.0.8 (

        Revision: ${svn.Revision} )

14:59:29,812 INFO  [Dialect] Using dialect: org.hibernate.dialect.MySQLDialect

14:59:29,828 INFO  [TransactionFactoryFactory] Transaction strategy: org.hibernate.ejb.transaction.JoinableCMTTransactionFactory

14:59:29,828 INFO  [TransactionManagerLookupFactory] instantiating TransactionManagerLookup:

        org.hibernate.transaction.JBossTransactionManagerLookup

14:59:29,828 INFO  [TransactionManagerLookupFactory] instantiated TransactionManagerLookup

14:59:29,828 INFO  [SettingsFactory] Automatic flush during beforeCompletion(): disabled

14:59:29,828 INFO  [SettingsFactory] Automatic session close at end of transaction: disabled

14:59:29,828 INFO  [SettingsFactory] JDBC batch size: 15

14:59:29,828 INFO  [SettingsFactory] JDBC batch updates for versioned data: disabled

14:59:29,828 INFO  [SettingsFactory] Scrollable result sets: enabled

14:59:29,828 INFO  [SettingsFactory] JDBC3 getGeneratedKeys(): enabled

14:59:29,828 INFO  [SettingsFactory] Connection release mode: auto

14:59:29,828 INFO  [SettingsFactory] Maximum outer join fetch depth: 2

14:59:29,828 INFO  [SettingsFactory] Default batch fetch size: 1

14:59:29,828 INFO  [SettingsFactory] Generate SQL with comments: disabled

14:59:29,828 INFO  [SettingsFactory] Order SQL updates by primary key: disabled

14:59:29,828 INFO  [SettingsFactory] Order SQL inserts for batching: disabled

14:59:29,828 INFO  [SettingsFactory] Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory

14:59:29,828 INFO  [ASTQueryTranslatorFactory] Using ASTQueryTranslatorFactory

14:59:29,828 INFO  [SettingsFactory] Query language substitutions: {}

14:59:29,828 INFO  [SettingsFactory] JPA-QL strict compliance: enabled

14:59:29,828 INFO  [SettingsFactory] Second-level cache: enabled

14:59:29,828 INFO  [SettingsFactory] Query cache: disabled

14:59:29,828 INFO  [SettingsFactory] Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge

14:59:29,828 INFO  [RegionFactoryCacheProviderBridge] Cache provider: org.hibernate.cache.HashtableCacheProvider

14:59:29,828 INFO  [SettingsFactory] Optimize cache for minimal puts: disabled

14:59:29,828 INFO  [SettingsFactory] Cache region prefix: persistence.unit:unitName=#demo

14:59:29,828 INFO  [SettingsFactory] Structured second-level cache entries: disabled

14:59:29,828 INFO  [SettingsFactory] Statistics: disabled

14:59:29,828 INFO  [SettingsFactory] Deleted entity synthetic identifier rollback: disabled

14:59:29,828 INFO  [SettingsFactory] Default entity-mode: pojo

14:59:29,828 INFO  [SettingsFactory] Named query checking : enabled

14:59:29,828 INFO  [SessionFactoryImpl] building session factory

14:59:29,859 INFO  [SessionFactoryObjectFactory] Factory name: persistence.unit:unitName=#demo

14:59:29,859 INFO  [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=

        org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}

14:59:29,875 INFO  [SessionFactoryObjectFactory] Bound factory to JNDI name: persistence.unit:unitName=#demo

14:59:29,875 WARN  [SessionFactoryObjectFactory] InitialContext did not implement EventContext

14:59:29,875 INFO  [SchemaExport] Running hbm2ddl schema export

14:59:29,875 INFO  [SchemaExport] exporting generated schema to database

14:59:29,953 INFO  [SchemaExport] schema export complete

14:59:29,953 INFO  [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=

        org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}

14:59:30,140 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EntityBeanTest.jar,name=StudentDAO,service=EJB3

14:59:30,140 INFO  [EJBContainer] STARTED EJB: com.ejb.dao.StudentDAO ejbName: StudentDAO

14:59:30,218 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   StudentDAO/remote - EJB3.x Default Remote Business Interface

   StudentDAO/remote-com.ejb.dao.StudentDAORemote - EJB3.x Remote Business Interface

从以上的信息可以看出,该发布过程执行了以下动作:

Ø 加载persistence.xml文件。

Ø 创建数据库表student,此时查看MySQL数据库就会看到新建的表student。

Ø 发布JNDI服务StudentDAO/remote。

这样我们就可以通过客户端访问JNDI服务StudentDAO/remote了。

6.1.7  开发客户端进行测试——StudentDAOClient.java
以上我们开发了实体Bean和会话Bean组件,并发布到了JBoss服务器中,下面我们来开发一个Java客户端程序,在该客户端创建一个实体对象,然后调用会话Bean组件插入该对象,往数据表中插入一条记录。

首先将实体类Student.java和接口类StudentDAORemote.java复制添加到测试项目EJBTestJava的对应包中,然后新建测试类StudentDAOClient.java,并开发如下代码:

程序6-5  测试类StudentDAOClient.java
import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Properties;

import javax.naming.InitialContext;

import javax.naming.NamingException;

import com.ejb.dao.StudentDAORemote;

import com.ejb.entitybean.Student;

public class StudentDAOClient {

    public static void main(String[] args) throws NamingException {

        Properties props = new Properties();

        props.setProperty("java.naming.factory.initial",

                "org.jnp.interfaces.NamingContextFactory");

        props.setProperty("java.naming.provider.url", "localhost:1099");

        props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

        try {

            InitialContext ctx = new InitialContext(props);

            StudentDAORemote studentDAO = (StudentDAORemote) ctx

                    .lookup("StudentDAO/remote");

           

            Student student = new Student();

            student.setName("刘中兵");

            student.setSex(true);

            student.setAge((short)25);

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

            student.setBirthday(format.parse("1981-05-04"));

            student.setTelephone("12345678");

            student.setAddress("北京");

           

            studentDAO.insert(student);

            System.out.println("已经插入一个学生记录!");

           

        } catch (NamingException e) {

            e.printStackTrace();

        } catch (ParseException e) {

            e.printStackTrace();

        }

    }

}

该类通过访问远程JNDI服务StudentDAO/remote,取得了远程会话Bean实例studentDAO。然后创建了一个Student实体对象,调用insert()函数插入该对象。运行该程序后,会在控制台中输出如下信息:

已经插入一个学生记录!

这就表明客户端的Java类已正确地将Student对象提交到远程会话Bean组件中了。此时再查看服务端JBoss的控制台,由于是第一次访问该实体Bean,因此JBoss会加载它并输出如下信息:

15:11:43,078 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a

         ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container

15:11:43,078 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a

         ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container

15:11:43,078 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public java.util.List

         com.ejb.dao.StudentDAO.list(int,int)

15:11:43,093 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public boolean

         com.ejb.dao.StudentDAO.deleteById(int)

15:11:43,109 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public com.ejb.entitybean.Student

         com.ejb.dao.StudentDAO.selectById(int)

15:11:43,125 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public boolean

         com.ejb.dao.StudentDAO.insert(com.ejb.entitybean.Student)

15:11:43,125 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public boolean

         com.ejb.dao.StudentDAO.update(com.ejb.entitybean.Student)

15:11:43,140 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public java.lang.String

         com.ejb.dao.StudentDAO.getNameById(int)

15:11:43,156 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public java.util.List

         com.ejb.dao.StudentDAO.list(int,int)

15:11:43,171 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public boolean

         com.ejb.dao.StudentDAO.deleteById(int)

15:11:43,171 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public com.ejb.entitybean.Student

         com.ejb.dao.StudentDAO.selectById(int)

15:11:43,187 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public boolean

         com.ejb.dao.StudentDAO.insert(com.ejb.entitybean.Student)

15:11:43,203 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public boolean

         com.ejb.dao.StudentDAO.update(com.ejb.entitybean.Student)

15:11:43,218 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public java.lang.String

         com.ejb.dao.StudentDAO.getNameById(int)

当以后再对该实体Bean进行访问时,就不会再输出以上的信息了,这是因为经过第一次加载后的实体Bean对象已经被实体管理器EntityManager缓存了,就会直接从缓存中取得该实体对象。

分享到:
评论

相关推荐

    h_JAVA 2应用编程150例.rar

    第1章 Java图形用户界面编程 1 实例1 布局管理 2 实例2 设计软件启动界面 9 实例3 实现多色窗口 11 实例4 切分窗口 13 实例5 丰富多彩的按钮 15 实例6 在窗口中显示背景图 16 实例7 在窗体中绘制图形 18 实例8 利用...

    Java数据库编程宝典3

    第1部分 介绍数据库、SQL和JDBC 第1章 关系型数据库 1.1 理解关系型数据库管理系统 1.1.1 关系模型 1.1.2 Codd法则 1.1.3 表、行、列和关键字 1.1.4 主键 1.1.5 外键 1.1.6 关系 1.1.7 视图 1.1.6 范式...

    Java数据库编程宝典1

    第1部分 介绍数据库、SQL和JDBC 第1章 关系型数据库 1.1 理解关系型数据库管理系统 1.1.1 关系模型 1.1.2 Codd法则 1.1.3 表、行、列和关键字 1.1.4 主键 1.1.5 外键 1.1.6 关系 1.1.7 视图 1.1.6 范式...

    Java数据库编程宝典2

    第1部分 介绍数据库、SQL和JDBC 第1章 关系型数据库 1.1 理解关系型数据库管理系统 1.1.1 关系模型 1.1.2 Codd法则 1.1.3 表、行、列和关键字 1.1.4 主键 1.1.5 外键 1.1.6 关系 1.1.7 视图 1.1.6 范式...

    Java数据库编程宝典4

    第1部分 介绍数据库、SQL和JDBC 第1章 关系型数据库 1.1 理解关系型数据库管理系统 1.1.1 关系模型 1.1.2 Codd法则 1.1.3 表、行、列和关键字 1.1.4 主键 1.1.5 外键 1.1.6 关系 1.1.7 视图 1.1.6 范式...

    JAVA上百实例源码以及开源项目源代码

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

    java源码包---java 源码 大量 实例

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

    java应用软件程序设计

    这里边包括:第1章 Java图形用户界面编程 1 实例1 布局管理 2 实例2 设计软件启动界面 9 实例3 实现多色窗口 11 实例4 切分窗口 13 实例5 丰富多彩的按钮 15 实例6 在窗口中显示背景图 16 实例...

    JAVA上百实例源码以及开源项目

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

    java源码包2

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

    java源码包3

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

    java源码包4

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java实现的FTP连接与数据浏览程序 1个目标文件 摘要:Java源码,网络相关,FTP Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 ...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Java实现的FTP连接与数据浏览程序 1个目标文件 摘要:Java源码,网络相关,FTP Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 ...

    JAVA程序开发大全---上半部分

    第1章 初识MyEclipse 1 1.1 MyEclipse简介 1 1.2 MyEclipse的安装 1 1.2.1 JDK的安装与配置 1 1.2.2 MyEclipse 7.0的安装和运行 4 1.3 获取和阅读MyEclipse帮助文档 5 1.4 本章小结 5 第2章 MyEclipse集成开发环境的...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    第一章 绪论 1.1. 选题背景 这几年,许多新名词涌入我们的视野:博客、圈子、播客、WAP等。这些都预示着我们进入了一个新的互联网阶段web 2.0,它是相对web 1.0的新的一类互联网应用的总称,是一次从核心内容到外部...

    低清版 大型门户网站是这样炼成的.pdf

    第1章 大型门户网站架构分析 3 1.1 大型门户网站与小型企业网站的区别 3 1.2 高性能、高负载门户网站架构剖析 9 1.2.1 服务器操作系统的选择 10 1.2.2 dns服务器bind 16 1.2.3 cache服务器squid 18 1.2.4 带...

Global site tag (gtag.js) - Google Analytics