EntityManager是应用程序操纵持久化数据的接口。它的作用与hibernate session类似。为了能够在一个请求周期中使用同一个session对象,在hibernate的解决方案中,提出了currentSession的概念,hibernate中的current session,可以跟JTA事务绑定,也可以跟当前线程绑定。在hibernate中,session管理着所有的持久化对象的数据。而在EJB3中,EntityManager管理着PersistenceContext,PersistenceContext正是被管理的持久化对象的集合。
PersistenceContext,称为持久化上下文,它一般包含有当前事务范围内的,被管理的实体对象(Entity)的数据。每个EntityManager,都会跟一个PersistenceContext相关联。PersistenceContext中存储的是实体对象的数据,而关系数据库中存储的是记录,EntityManager正是维护这种OR映射的中间者,它可以把数据从数据库中加载到PersistenceContext中,也可以把数据从PersistenceContext中持久化到数据库,EntityManager通过Persist、merge、remove、refresh、flush等操作来操纵PersistenceContext与数据库数据之间的同步!
对实体进行持久化就是将其插入到数据库中。你所持久化的是还未曾保存到数据库中的实体。要持久化一个实体,首先是为实体的实例分配内存,然后设置成员属性,并设置好与其他对象可能存在的任何关联关系。换言之,你可以像操作普通Java对象那样初始化一个entity bean。一旦完成这一步,你就可以调用EntityManager.persist()方法来保存该实体了。
例如,我们将一个学生实体保存到数据库:
- try {
- 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("北京");
- em.persist(student);
- } catch (Exception e) {
- e.printStackTrace();
- }
以上的代码将会在数据表student中插入一行记录,类似于执行了以下SQL语句:
- insert into student(name, sex, age, birthday, telephone, address)
- values('刘中兵', 1, 25, '1981-05-04', '12345678', '北京');
如果传递进persist()方法的参数不是实体Bean,则会引发IllegalArgumentException异常。
当调用persist()方法后,EntityManager会将Customer添加到等待数据库插入的队列中,对象实例即处于托管状态。实际的插入操作何时发生则取决于多种因素。如果在事务范围内调用了persist()方法,插入操作可能马上执行,也可能在事务提交时执行,这依赖于flush模式。如果传入 persist()方法的参数不是实体类型的,persist()方法将抛出Illegal- ArgumentException异常。在transaction-scoped persistence context里,事务范围外的persist()调用会引起TransactionRequiredException异常。而在extended persistence context中,事务范围外的persist()调用则是合法的;不过在persistence context与事务关联之前,数据库插入操作是不会被执行的