- 浏览: 483218 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
龘龘龘:
TrueBrian 写道有个问题,Sample 1中,为了控制 ...
What's New on Java 7 Phaser -
龘龘龘:
楼主总结的不错。
What's New on Java 7 Phaser -
TrueBrian:
有个问题,Sample 1中,为了控制线程的启动时机,博主实际 ...
What's New on Java 7 Phaser -
liguanqun811:
不知道楼主是否对zookeeper实现的分布式锁进行过性能测试 ...
Distributed Lock -
hobitton:
mysql的get lock有版本限制,否则get lock可 ...
Distributed Lock
4 EntityManagerFactory
4.1 Overview
EntityManagerFactory可以被注入到应用中,也可以通过以下方式创建:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("openjpa");
Persistence.createEntityManagerFactory方法通过在类路径上查找META-INF目录中的persistence.xml文件来获得EntityManagerFactory的配置,persistence.xml文件中可以定义多个persistence-unit。其name属性值可以作为Persistence.createEntityManagerFactory方法的参数,transaction-type用来指定是使用JTA,还是使用局部事务。以下是个persistence.xml文件的例子:
<?xml version="1.0"?> <persistence> <persistence-unit name="openjpa" transaction-type="RESOURCE_LOCAL" > <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <class>tutorial.Animal</class> <class>tutorial.Dog</class> <class>tutorial.Rabbit</class> <class>tutorial.Snake</class> <properties> <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:tutorial_database"/> <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/> <property name="openjpa.ConnectionUserName" value="sa"/> <property name="openjpa.ConnectionPassword" value=""/> <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/> </properties> </persistence-unit> </persistence>
EntityManagerFactory 实例是重量级对象。每个EntityManagerFactory 实例可能要维护metadata cache、object state cache、EntityManager pool、connection pool等等资源。如果应用程序不再使用EntityManagerFactory,那么应该及时关闭它以便释放资源。如果在一个或多个EntityManager处于活跃状态时试图关闭EntityManagerFactory,那么会导致一个IllegalStateException。
4.2 Persistence Context
Persistence context包含一组entities,这些entities都有唯一的persistent identity。在persistence context中,EntityManager管理entities的生命周期,entities可以访问datastore来获取persistent state。当persistence context结束的时候,被EntityManager管理的所有entities都变成detached状态。Detached entities不再被EntityManager管理,也不能访问datastore。有两种类型的persistent context:transaction persistence context和extended persistence context。
4.2.1 Transaction Persistence Context
在transaction persistence context模型中,EntityManager为每一个事务开始一个新的persistence context。当事务被提交或者回滚后,persistence context也就自动结束,被EntityManager管理的所有entity都变成detached状态。此时如果访问entity上尚未被加载的字段(例如lazy fetch字段)会导致没有定义的结果。
如果不在事务中通过EntityManager访问datastore,那么EntityManager会对每一次方法调用都创建一个新的persistence context。当方法调用结束时,persistence context也自动结束。例如当在事务之外调用EntityManager.find方法,EntityManager会创建一个临时的persistence context,并在这个临时的persistence context中访问datastore。当EntityManager.find方法结束时,临时的persistence context自动结束,并且EntityManager.find方法会返回一个detached entity。如果用相同的identity object再次调用EntityManager.find方法,那么会得到一个新的detached entity。以下是个描述transaction persistence context模型的行为的例子:
EntityManager em; // injected ... // outside a transaction: // each operation occurs in a separate persistence context, and returns // a new detached instance Magazine mag1 = em.find(Magazine.class, magId); Magazine mag2 = em.find(Magazine.class, magId); assertTrue(mag2 != mag1); ... // transaction begins: // within a transaction, a subsequent lookup doesn't return any of the // detached objects. however, two lookups within the same transaction // return the same instance, because the persistence context spans the // transaction Magazine mag3 = em.find(Magazine.class, magId); assertTrue(mag3 != mag1 && mag3 != mag2); Magazine mag4 = em.find(Magazine.class (magId); assertTrue(mag4 == mag3); ... // transaction commits: // once again, each operation returns a new instance Magazine mag5 = em.find(Magazine.class, magId); assertTrue(mag5 != mag3);
4.2.2 Extended Persistence Context
在extended persistence context模型中,不论是否在事务内,EntityManager在其整个生命周期内维护相同一个persistence context。所有通过EntityManager得到的entities都被EntityManager管理,只有在EntityManager被关闭,或者entity被序列化的时候,entity才变成detached状态。
以下是个描述extended persistence context模型的行为的例子:
EntityManagerFactory emf = ... EntityManager em = emf.createEntityManager(); // persistence context active for entire life of EM, so only one entity // for a given persistent identity Magazine mag1 = em.find(Magazine.class, magId); Magazine mag2 = em.find(Magazine.class, magId); assertTrue(mag2 == mag1); em.getTransaction().begin(); // same persistence context active within the transaction Magazine mag3 = em.find(Magazine.class, magId); assertTrue(mag3 == mag1); Magazine mag4 = em.find(Magazine.class (magId); assertTrue(mag4 == mag1); em.getTransaction.commit (); // when the transaction commits, instance still managed Magazine mag5 = em.find(Magazine.class, magId); assertTrue(mag5 == mag1); // instance finally becomes detached when EM closes em.close();
5 EntityManager
EntityManager接口的方法可以大致分为以下几类。
5.1 Transaction Association
public EntityTransaction getTransaction ();
EntityManager实例和EntityTransaction实例之间是一对一的关系。 通过getTransaction方法可以得到与EntityManager关联的EntityTransaction实例。
5.2 Entity Identity Management
EntityManager负责管理entities,以下的这些方法的行为会因persistence context(transaction persistence context或者extended persistence context)的不同而有差异。
public <T> T find(Class<T> cls, Object oid);
find方法返回persistent identity指定的entity。 如果这个entity存在于当前的persistence context中,那么返回值是被缓存的对象;否则会创建一个新的entity,并从datastore中加载相关的persistent state。如果datastore不存在持有指定persistent identity的记录,那么这个方法返回null。
public <T> T getReference(Class<T> cls, Object oid);
getReference方法与find相似。不同的是:如果缓存中没有指定的entity,EntityManager会创建一个新的entity,不是立即访问datastore(不加载persistent state),而是在第一次访问某个持久字段的时候才加载相应的persistent state。此外,getReference 方法不返回null,如果在datastore中找不到相应的entity,这个方法会抛出EntityNotFoundException。
public boolean contains(Object entity);
如果当前的persistence context 包含指定的entity,那么返回true;否则返回false。
5.3 Cache Management
public void flush();
Flush方法把当前事务中所有的修改写入到datastore中。如果EntityManager没有连接到datastore,那么EntityManager首先会获取一个连接并一直持有到事务结束。Flush方法抛出的任何异常都会导致事务回滚。如果调用flush方法时没有一个活跃的事务,那么flush方法会抛出TransactionRequiredException。
public FlushModeType getFlushMode(); public void setFlushMode(FlushModeType flushMode);
EntityManager的FlushMode 属性用来指定是否在执行query之前进行flush。这可以确保当前事务中的任何修改会体现在query的结果中。此外也可以在query实例上设置FlushMode。它有以下两个可选值:
- COMMIT: 只是在事务提交的时候flush。当前事务中的修改可能不会体现在query的结果中。
- AUTO: 在需要的时候进行flush以确保当前事务中的任何修改都会体现在query的结果中。
OpenJPA 只在当前事务的任何修改可能会影响到将要执行的query的结果时才进行flush。
public void clear();
Clear方法会结束当前的persistence context,被EntityManager管理的所有entities变成detached状态。
5.4 Query Factory
public Query createQuery(String query);
createQuery方法根据提供的Java Persistence Query Language (JPQL) string来创建一个query。
public Query createNamedQuery(String name);
createNamedQuery方法用来得到通过metadata定义的命名query。
public Query createNativeQuery(String sql); public Query createNativeQuery(String sql, Class resultCls); public Query createNativeQuery(String sql, String resultMapping);
以上方法用来创建datastore特有的native queries。例如在关系型数据库中使用的Structured Query Language (SQL)。
5.5 Closing
public boolean isOpen(); public void close();
当不再使用EntityManager 的时候,需要及时关闭它以便释放资源。如果EntityManager 已经关闭,那么除了调用isOpen 方法外,调用EntityManager上的其它方法会导致IllegalStateException。不能在一个事务正在进行中的时候关闭EntityManager。
5.6 Entity Lifecycle Management
5.6.1 public void persist(Object entity);
persist方法用于将新创建的entity纳入EntityManager的管理,在下一次的flush或者commit时,这个entity会被插入到datastore中。这个方法只能在一个活跃的事务环境中调用。它的行为如下:
- 如果是新entity,那么它会被EntityManager管理。
- 如果这个entity已经被EntityManager管理,那么会被忽略。
- 如果这个entity之前被remove,那么它会重新被管理。
- 如果这个entity的状态是detached,那么会导致IllegalArgumentException。
以下是个简单的例子:
import java.util.Iterator; import java.util.List; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.OneToMany; import org.apache.openjpa.persistence.FetchAttribute; import org.apache.openjpa.persistence.FetchGroup; import org.apache.openjpa.persistence.FetchGroups; @Entity @FetchGroups({ @FetchGroup(name="detail", attributes={ @FetchAttribute(name="grade"), @FetchAttribute(name="magazines") }) }) public class Publisher { private int id; private String name; private String grade; private List<Magazine> magazines; public String toString() { StringBuffer sb = new StringBuffer(); sb.append("id: " + getId()); sb.append(", name: " + getName()); sb.append(", grade: " + getGrade()); sb.append(", magazines["); if(getMagazines() != null) { for(Iterator<Magazine> iter = getMagazines().iterator(); iter.hasNext(); ) { sb.append(iter.next().toString()); if(iter.hasNext()) { sb.append("; "); } } } sb.append("]"); return sb.toString(); } @Id public int getId() { return id; } public void setId(int id) { this.id = id; } @Basic public String getName() { return name; } public void setName(String name) { this.name = name; } @Basic(fetch=FetchType.LAZY) public String getGrade() { return grade; } public void setGrade(String grade) { this.grade = grade; } @OneToMany(mappedBy="publisher", cascade=CascadeType.ALL, fetch=FetchType.LAZY) public List<Magazine> getMagazines() { return magazines; } public void setMagazines(List<Magazine> magazines) { this.magazines = magazines; } }
import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.IdClass; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; @Entity @IdClass(Magazine.MagazineId.class) public class Magazine { @Id private String isbn; @Id private String title; @ManyToOne(cascade=CascadeType.ALL) @JoinColumn(name = "publisherId", referencedColumnName = "id") private Publisher publisher; public String toString() { StringBuffer sb = new StringBuffer(); sb.append("isbn: " + isbn); sb.append(", title: " + title); return sb.toString(); } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Publisher getPublisher() { return publisher; } public void setPublisher(Publisher publisher) { this.publisher = publisher; } public static class MagazineId { private String isbn; private String title; public MagazineId() { } public MagazineId(String isbn, String title) { this.isbn = isbn; this.title = title; } public boolean equals(Object obj) { if(this == obj) { return true; } if(!(obj instanceof MagazineId)) { return false; } MagazineId rhs = (MagazineId)obj; boolean b1 = (isbn == rhs.isbn || (isbn != null && isbn.equals(rhs.isbn))); boolean b2 = (title == rhs.title || (title != null && title.equals(rhs.title))); return b1 && b2; } public int hashCode(){ int h1 = (isbn == null ? 0 : isbn.hashCode()); int h2 = (title == null ? 0 : title.hashCode()); return h1 ^ h2; } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("isbn: " + isbn); sb.append(", title: " + title); return sb.toString(); } } }
Publisher p1 = new Publisher(); p1.setId(id); p1.setName("publisher1"); p1.setGrade("excellent"); p1.setMagazines(new ArrayList<Magazine>()); Magazine m1 = new Magazine(); m1.setIsbn("isbn1"); m1.setTitle("title1"); m1.setPublisher(p1); p1.getMagazines().add(m1); Magazine m2 = new Magazine(); m2.setIsbn("isbn2"); m2.setTitle("title2"); m2.setPublisher(p1); p1.getMagazines().add(m2); EntityManagerem = entityManagerFactory.createEntityManager(); em.getTransaction().begin(); em.persist(p1); em.getTransaction().commit();
5.6.2 public void remove(Object entity);
remove方法用于删除被管理的entity。在下一次的flush或者commit时,这个entity会从datastore中删除。这个方法只能在一个活跃的事务环境中调用。它的行为如下:
- 如果是新entity,那么会被忽略。
- 如果是已经被管理的entity,那么它会被删除。
- 如果这个entity之前被remove,那么会被忽略。
- 如果这个entity的状态是detached,那么会导致IllegalArgumentException。
5.6.3 public void refresh(Object entity);
refresh方法用于确保entity的persistent state和datastore中的persistent state同步。它的行为如下:
- 如果是新entity,那么会被忽略。
- 如果是已经被管理的entity,那么刷新它的persistent state。
- 如果这个entity之前被remove,那么会被忽略。
- 如果这个entity的状态是detached,那么会导致IllegalArgumentException。
5.6.4 public Object merge(Object entity);
有些情况下,你需要编辑一个处于detached状态的entity,然后重新将这个entity纳入到EntityManager的管理中,并将对其persistent state的修改更新到datastore中。Merge方法返回该entity受管理的一份拷贝。这个方法只能在一个活跃的事务环境中调用。它的行为如下:
- 如果是新entity,那么会创建该entity的一份拷贝,并将这份拷贝纳入EntityManager的管理。
- 如果是已经被管理的entity,那么会被忽略。
- 如果这个entity之前被remove,那么会导致IllegalArgumentException。
- 如果这个entity的状态是detached,如果EntityManager中已经管理了具有相同的identity的entity B,那么会将原始entity的persistent state拷贝到entity B中;否则会创建该entity的一份拷贝,并将这份拷贝纳入EntityManager的管理。
以下是个简单的例子:
p1.setName("publisher2"); EntityManager em = entityManagerFactory.createEntityManager(); em.getTransaction().begin(); em.merge(obj); em.getTransaction().commit();
5.6.5 public void lock (Object entity, LockModeType mode);
lock方法通过指定的LockModeType 来对entity加锁。LockModeType 有以下两个可选值:
- READ: 在其它事务中可以读取,但是不能更新。
- WRITE: 在其它事务中不可以读取或更新。在当前事务提交后,无论被WRITE lock锁定的entities是否改变,其version将会自动增加。
5.6.6 Detach and Attach
除了JPA定义的detach和attach API之外,OpenJPA还支持更多的特性。例如OpenJPAEntityManager提供以下方法:
public Object detach(Object pc); public Object[] detachAll(Object... pcs); public Collection detachAll(Collection pcs);
以上的detach方法返回给定entity的detached状态的拷贝。在detach在当前事务中被修改过的entity之前,flush方法会被调用,以便将这些修改保存到datastore中。由于detached entity不能访问datastore,因此有时候需要在detach之前加载一些persistent state(例如某些lazy fetch字段)。尽管可以通过手工编码完成,OpenJPA也提供了一些特性来自动完成类似的工作。例如DetachState,它有以下可选值:
- loaded: 保持已经加载的字段,对于没有加载的字段则保持不变。这是缺省值。
- fetch-groups: 根据fetch group来决定需要加载的字段。
- all: 加载所有的字段。
继续5.6.1中的例子:
EntityManager em = entityManagerFactory.createEntityManager(); Publisher p2 = (Publisher)em.find(Publisher.class, id); em.close(); System.out.println(p2.toString());
以上例子中p2在em.close()之后变成detached状态。由于采用了缺省的DetachState,因此没有加载lazy fetch字段grade和magazines。输出如下:
id: 1, name: publisher1, grade: null, magazines[]
em = entityManagerFactory.createEntityManager(); Publisher p4 = (Publisher)em.find(Publisher.class, id); p4.getGrade(); p4.getMagazines(); em.close(); System.out.println(p4.toString());
以上例子中p4在em.close()之后变成detached状态。虽然采用了缺省的DetachState,但是由于程序中显式访问了lazy fetch字段,所以grade和magazines被加载,并且在detach之后仍然可以访问。输出如下:
id: 1, name: publisher1, grade: excellent, magazines[isbn: isbn1, title: title1; isbn: isbn2, title: title2]
em = entityManagerFactory.createEntityManager(); ((OpenJPAEntityManager)em).setDetachState(DetachStateType.ALL); Publisher p5 = (Publisher)em.find(Publisher.class, id); em.close(); System.out.println(p5.toString());
以上例子中p5在em.close()之后变成detached状态。由于采用了 DetachStateType.ALL,因此所有的lazy fetch字段在detach之前都自动被加载,并且在detach之后仍然可以访问。输出如下:
id: 1, name: publisher1, grade: excellent, magazines[isbn: isbn1, title: title1; isbn: isbn2, title: title2]
em = entityManagerFactory.createEntityManager(); ((OpenJPAEntityManager)em).setDetachState(DetachStateType.FETCH_GROUPS); ((OpenJPAEntityManager)em).getFetchPlan().addFetchGroup("detail"); Publisher p6 = (Publisher)em.find(Publisher.class, id); em.close(); System.out.println(p6.toString());
以上例子中p6在em.close()之后变成detached状态。由于采用了 DetachStateType. FETCH_GROUPS,而Publisher中名为"detail"的fetch group定义了要额外加载grade和magazines,因此grade和magazines被加载,并且在detach之后仍然可以访问。输出如下:
id: 1, name: publisher1, grade: excellent, magazines[isbn: isbn1, title: title1; isbn: isbn2, title: title2]
发表评论
-
Terracotta in Action (3)
2009-03-25 09:20 51453 Inside Terracotta 3.1 Core T ... -
Terracotta in Action (2)
2009-03-21 21:09 47022. Terracotta Eclipse Plugin ... -
Terracotta in Action (1)
2009-03-19 21:52 62861. Introduction Terraco ... -
OpenEJB (4)
2008-05-11 09:05 3187本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenEJB (3)
2008-05-11 09:04 2728本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenEJB (2)
2008-05-11 09:03 3321本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenEJB (1)
2008-05-10 22:39 5111本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenJPA (7)
2008-03-25 21:56 357510 Miscellaneous Features 10 ... -
OpenJPA (6)
2008-03-23 21:33 63438 Object Locking 8.1 Configu ... -
OpenJPA (5)
2008-03-18 22:38 50527 Inheritance 对象使用引用以便关联到其 ... -
OpenJPA (4)
2008-03-11 23:27 71116 Query 6.1 JPQL Queries 6.1. ... -
OpenJPA (2)
2008-03-05 23:59 72993 Metadata 通过javax.persist ... -
OpenJPA (1)
2008-03-04 23:11 68821 Overview Apache OpenJPA是 ... -
ActiveMQ in Action (7)
2008-02-27 14:33 126792.6.7 Wildcards Wil ... -
ActiveMQ in Action (6)
2008-02-26 15:22 137992.6 Features ActiveMQ包含了很多 ... -
ActiveMQ in Action (5)
2008-02-26 00:35 136022.5 Clustering ActiveMQ从多种 ... -
ActiveMQ in Action (4)
2008-02-26 00:21 112792.4 Security ActiveMQ ... -
ActiveMQ in Action (3)
2008-02-26 00:16 106392.3 Persistence 2.3.1 AMQ Mess ... -
ActiveMQ in Action (2)
2008-02-25 23:58 132782.2 Transport ActiveMQ目前支持 ... -
ActiveMQ in Action (1)
2008-02-25 23:18 238811 JMS 在介绍ActiveMQ ...
相关推荐
OpenJPA,全称Open Java Persistence API,是Java平台上的一个开源对象关系映射(ORM)框架,它实现了Java Persistence API(JPA),用于管理Java应用程序中的持久化数据。在这个"openjpademo"示例中,我们将会探讨...
默认情况下,当应用程序第一次获取实体标识时,OpenJPA 框架从数据库中一次性获取 50 个连续的实体标识缓存起来,当下一次应用程序需要获取实体标识时,OpenJPA 将首先检测缓存中是否存在实体标识,如果存在,Open...
OpenJPA OpenJPA 是 Apache 组织提供的开源项目,它实现了 EJB 3.0 中的 JPA 标准,为开发者提供功能强大、使用简单的持久化数据管理框架。OpenJPA 封装了和关系型数据库交互的操作,让开发者把注意力集中在编写...
OpenJPA,全称Open Java Persistence API,是Apache软件基金会的一个开源项目,它实现了Java持久化API(Java Persistence API,JPA),为Java开发者提供了一种标准的方式来管理和持久化应用程序中的对象。...
**Spring和OpenJPA集成详解** 在Java世界中,Spring框架和OpenJPA(Open Java Persistence)是两个非常重要的组件。Spring作为一个全面的轻量级应用框架,提供了大量的功能,包括依赖注入、AOP(面向切面编程)、...
OpenJPA2是一个开源的对象关系映射(ORM)框架,它是Java Persistence API(JPA)规范的实现。在这个“Open JPA2 employee简单例子”中,我们将深入理解如何使用OpenJPA2来处理数据库中的员工数据。这个示例将帮助...
OpenJPA(Java Persistence API)则是Java平台上的一个ORM(对象关系映射)工具,它实现了JSR-317规范,使得开发者可以方便地在Java应用程序中操作数据库。本篇将详细讲解如何在Spring项目中集成并使用OpenJPA。 ...
OpenJPA(Open Java Persistence API)是Apache软件基金会下的一个开源项目,它是Java持久层标准JPA(Java Persistence API)的一个实现。JPA是Java EE平台中的一个重要组件,用于管理和处理应用程序中的对象-关系...
**JSF与OpenJPA整合** 涉及到在JSF应用中使用OpenJPA进行数据访问。这通常包括配置OpenJPA的数据源、实体管理器工厂,以及在JSF Managed Beans中注入实体管理器,以便在处理用户请求时执行CRUD操作。JSF的事件驱动...
3. **事务管理**:OpenJPA集成了Java EE的事务管理机制,支持声明式事务和编程式事务。开发者可以使用TransactionAttribute注解或在代码中手动管理事务边界。 4. **缓存机制**:OpenJPA提供了本地缓存和第二级缓存...
### OpenJPA官方手册知识点概览 #### 一、引言 - **OpenJPA**:作为Apache项目的一部分,OpenJPA是一个开源的Java持久化框架(Java Persistence Framework),它支持Java Persistence API (JPA) 的规范。OpenJPA...
安装OpenJPA的步骤通常包括下载OpenJPA的jar文件,将其添加到服务器的类路径中,并在服务器配置中指定OpenJPA作为默认的持久化提供者。 接下来,我们需要创建一个JPA项目。这涉及定义实体类,这些类代表数据库中的...
Spring MVC和OpenJPA是Java开发中常用的两个框架,它们分别在Web应用和持久层处理上发挥着重要作用。Spring MVC是Spring框架的一部分,用于构建高效、灵活的Web应用程序,而OpenJPA则是一个实现了Java Persistence ...
OpenJPA API 文档 chm格式
### Apache OpenJPA 2.1 用户指南:Java Persistence API 的深入解析 #### 一、简介 Apache OpenJPA 2.1 是基于 Sun Microsystems 的 Java Persistence 2.0 API (JSR-317 JPA 2.0) 规范实现的一种透明持久化 Java ...
Apache OpenJPA-自述文件 前言 感谢您下载此版本的Apache OpenJPA。 Apache OpenJPA是Java Persistence API规范的实现。 执照 此存储库的内容已根据Apache License 2.0 许可 更多信息 可以在openjpa-project子目录...
### OpenJPA-Manual 关键知识点解析 #### 一、OpenJPA介绍 **1.1 关于本文档** 本文档旨在提供一个全面且深入的指南,帮助开发人员理解和掌握Java Persistence API(JPA)的核心概念及其在Apache OpenJPA中的实现...
Openjpa2.2+Mysql+Maven+Servlet+JSP 博客源码: http://blog.csdn.net/shenhonglei1234/article/details/10394379
3. **缓存机制**:OpenJPA提供了一级缓存和二级缓存,一级缓存是事务级别的,用于存储当前事务中的实体;二级缓存可跨事务,用于共享数据,提高性能。 4. **事务管理**:OpenJPA集成了Java EE的事务管理机制,可以...