当前位置:首页 > jpatemplate
14. } finally {
15. closeEntityManager(em); 16. } 17. }
使用EntityManagerFactory获取EntityManager进行操作,看到这还能忍受冗长的代码和事务管理吗?Spring同样提供JpaTemplate模板类来简化这些操作。
大家有没有注意到此处的模型对象能自动映射到数据库,这是因为Hibernate JPA实现默认自动扫描类路径中的@Entity注解类及*.hbm.xml映射文件,可以通过更改Hibernate JPA属性“hibernate.ejb.resource_scanner”,并指定
org.hibernate.ejb.packaging.Scanner接口实现来定制新的扫描策略。
8.4.2 使用JpaTemplate
JpaTemplate模板类用于简化事务管理及常见操作,类似于JdbcTemplate模板类,对于复杂操作通过提供JpaCallback回调接口来允许更复杂的操作。 接下来示例一下JpaTemplate的使用:
1、修改Spring配置文件(chapter8/applicationContext-jpa.xml),添加JPA事务管理器:
java代码:
Java代码
1. ctionManager\ 2. y\3.
? txManager:指定事务管理器,JPA使用JpaTransactionManager事务管理器
实现,通过entityManagerFactory指定EntityManagerFactory;用于支持Java SE环境的JPA扩展的持久化上下文(EXTENDED Persistence Context)。
2、修改JPATest类,添加类变量ctx,用于后边使用其获取事务管理器使用:
java代码:
Java代码
1. package cn.javass.spring.chapter8; 2. public class JPATest {
3. private static EntityManagerFactory entityManagerFactory; 4. private static ApplicationContext ctx; 5. @BeforeClass
6. public static void beforeClass() {
7. String[] configLocations = new String[] {
8. \9. \
10. ctx = new ClassPathXmlApplicationContext(configLocations); 11. entityManagerFactory = ctx.getBean(EntityManagerFactory.class
); 12. } 13. } 14.
3)JpaTemplate模板类使用:
java代码:
Java代码
1. @Test
2. public void testJpaTemplate() {
3. final JpaTemplate jpaTemplate = new JpaTemplate(entityManagerFacto
ry);
4. final UserModel2 model = new UserModel2(); 5. model.setMyName(\
6. PlatformTransactionManager txManager = ctx.getBean(PlatformTrans
actionManager.class);
7. new TransactionTemplate(txManager).execute( 8. new TransactionCallback
10. public Void doInTransaction(TransactionStatus status) { 11. jpaTemplate.persist(model); 12. return null; 13. } 14. });
15. String COUNT_ALL = \
16. Number count = (Number) jpaTemplate.find(COUNT_ALL).get(0); 17. Assert.assertEquals(1, count.intValue()); 18. } 19. 20.
? jpaTemplate:可通过new JpaTemplate(entityManagerFactory)方式创建; ? txManager:通过ctx.getBean(PlatformTransactionManager.class)获取事
务管理器;
? TransactionTemplate:通过new TransactionTemplate(txManager)创建
事务模板对象,并通过execute方法执行TransactionCallback 回调中的doInTransaction方法中定义需要执行的操作,从而将由模板类通过txManager事务管理器来进行事务管理,此处是调用 jpaTemplate对象的persist方法进行持久化;
? jpaTemplate.persist():根据JPA规范,在JPA扩展的持久化上下文,该操
作必须运行在事务环境,还有persist()、 merge()、remove()操作也必须运行在事务环境;
? jpaTemplate.find():根据JPA规范,该操作无需运行在事务环境,还有find()、
getReference()、 refresh()、detach()和查询操作都无需运行在事务环境。
此实例与Hibernate和Ibatis有所区别,通过JpaTemplate模板类进行如持久化等操作时必须有运行在事务环境中,否则可能抛出如下异常或警告:
? “javax.persistence.TransactionRequiredException:Executing an
update/delete query”:表示没有事务支持,不能执行更新或删除操作; ? 警告“delaying identity-insert due to no transaction in progress”:
需要在日志系统启动debug模式才能看到,表示在无事务环境中无法进行持久化,而选择了延迟标识插入。
以上异常和警告是没有事务造成的,也是最让人困惑的问题,需要大家注意。
8.4.3 集成JPA及最佳实践
类似于JdbcDaoSupport类,Spring对JPA也提供了JpaDaoSupport类来支持一致的数据库访问。JpaDaoSupport也是DaoSupport实现: 接下来示例一下Spring集成JPA的最佳实践:
1、 定义Dao接口,此处使用cn.javass.spring.chapter7.dao. IUserDao:
2、 定义Dao接口实现,此处是JPA实现:
java代码:
Java代码
1. package cn.javass.spring.chapter8.dao.jpa; 2. //省略import
3. @Transactional(propagation = Propagation.REQUIRED)
4. public class UserJpaDaoImpl extends JpaDaoSupport implements IUser
Dao {
5. private static final String COUNT_ALL_JPAQL = \
m UserModel\6. @Override
7. public void save(UserModel model) { 8. getJpaTemplate().persist(model); 9. }
10. @Override
11. public int countAll() { 12. Number count =
13. (Number) getJpaTemplate().find(COUNT_ALL_JPAQL).get(0);
14. return count.intValue(); 15. } 16. }
共分享92篇相关文档