Spring3、hibernate4、JPA配置在自己的电脑上试了下,没有找到事务管理解决的办法,今天图书馆看书,参考书里面的配置解决了事务管理问题,在此记录,顺便与诸君共享
首先是applicationContext的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 数据源定义,使用Apache c3p0 连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/zjgcmcc?useUnicode=true&characterEncoding=utf-8" />
<property name="user" value="root" />
<property name="password" value="sunkai" />
<property name="checkoutTimeout" value="5000" />
<property name="minPoolSize" value="2" />
<property name="maxPoolSize" value="10" />
<property name="maxStatements" value="100" />
<property name="acquireIncrement" value="2" />
</bean>
<!-- 将 EntityManager 对象注射到标有 @PersistenceContext 的属性上 -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- EntityManagerFanctory 对象,用户产生EntityManager -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" destroy-method="destroy">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="hibernateJPA" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
</bean>
</property>
</bean>
<!-- 事务管理配置 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 将事务管理配置到有@Trancactional 的类、方法上
<tx:annotation-driven transaction-manager="transactionManager" />
-->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="remove*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="businessService"
expression="execution(* zjgcmcc.web.service.*.*(..))" />
<aop:advisor advice-ref="transactionAdvice" pointcut-ref="businessService" />
</aop:config>
<!--引入dao、service及其他bean设置-->
<import resource="beans.xml" />
</beans>
Dao类、Service类、Controller类及其他bean配置在一个单独的beans.xml文件中:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 基于JPA的通用基础Dao -->
<bean id="baseDao" class="zjgcmcc.web.dao.impl.BaseDao"></bean>
<bean id="userService" class="zjgcmcc.web.service.UserService">
<property name="userDao" ref="baseDao"></property>
</bean>
</beans>
此处是persistence.xml的文件配置:
<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" >
<persistence-unit name="hibernateJPA" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- entity classes -->
<class>zjgcmcc.web.entity.Order</class>
<class>zjgcmcc.web.entity.BaseEntity</class>
<class>zjgcmcc.web.entity.TB_Dept</class>
<class>zjgcmcc.web.entity.TB_User</class>
<class>zjgcmcc.web.entity.TB_Role</class>
<!-- 下方为hibernate的一些属性设置-->
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.jdbc.fetch_size" value="18" />
<property name="hibernate.jdbc.batch_size" value="10" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
来看看通用的Dao类的写法:
接口:IBaseDao.java
package zjgcmcc.web.dao;
import java.io.Serializable;
import java.util.List;
public interface IBaseDao<T,ID extends Serializable> {
public T findById(T t,ID id);
public List<T> query(String sql,T t);
public int add(T object);
public int update(T object);
public int update(String sql);
public int delete(T object);
public void flush();
}
Dao的接口实现类:BaseDao.java
package zjgcmcc.web.dao.impl;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import zjgcmcc.web.dao.IBaseDao;
public class BaseDao<T extends Serializable, ID extends Serializable> implements IBaseDao<T, ID> {
@PersistenceContext
private EntityManager entityManager;
@Override
public T findById(T t, ID id) {
// TODO Auto-generated method stub
T find = (T) this.entityManager.find(t.getClass(), id);
return find;
}
@Override
public List<T> query(String sql, T t) {
// TODO Auto-generated method stub
return this.entityManager.createNativeQuery(sql,t.getClass())
.getResultList();
}
@Override
public int add(T object) {
// TODO Auto-generated method stub
int result = 1;
try {
this.entityManager.persist(object);
} catch (Exception e) {
result = 0;
}
return result;
}
@Override
public int update(T object) {
// TODO Auto-generated method stub
int result = 1;
try {
this.entityManager.merge(object);
} catch (Exception e) {
result = 0;
}
return result;
}
@Override
public int update(String sql) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int delete(T object) {
// TODO Auto-generated method stub
try {
this.entityManager.remove(object);
return 1;
} catch (Exception e) {
return 0;
}
}
@Override
public void flush() {
// TODO Auto-generated method stub
this.entityManager.flush();
}
}
接下来是一个业务层Service类:UserService.java
package zjgcmcc.web.service;
import zjgcmcc.web.dao.impl.BaseDao;
import zjgcmcc.web.entity.TB_User;
public class UserService {
private BaseDao<TB_User,String> userDao;
public BaseDao<TB_User, String> getUserDao() {
return userDao;
}
public void setUserDao(BaseDao<TB_User, String> userDao) {
this.userDao = userDao;
}
public void addUser(TB_User user){
this.userDao.add(user);
}
}
最后是一个单元测试:UserJPATest.java
package test;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import zjgcmcc.web.entity.TB_Dept;
import zjgcmcc.web.entity.TB_Role;
import zjgcmcc.web.entity.TB_User;
import zjgcmcc.web.service.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserJPATest {
@Autowired private UserService userService;
@Autowired EntityManagerFactory emf;
@Autowired JpaTransactionManager transactionManager;
@Test public void test(){
TB_Dept dept=new TB_Dept();
TB_Role role=new TB_Role();
TB_User user=new TB_User();
dept.setD_id("03");
dept.setD_name("第三分中心");
role.setR_id("0301");
role.setR_name("主任");
role.setR_dept(dept);
List<TB_Role> roles=new ArrayList<TB_Role>();
roles.add(role);
user.setU_id("030100");
user.setU_name("A");
user.setU_roles(roles);
System.out.println((userService==null));
this.userService.addUser(user);
}
}
三个Entity类:
TB_Dept.java:
package zjgcmcc.web.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="tb_dept")
public class TB_Dept extends BaseEntity{
private static final long serialVersionUID = -1844975459250411764L;
@Id
@Column(name="d_id")
private String d_id;
@Column(name="d_name")
private String d_name;
@Column(name="d_level",nullable=false)
private int d_level;
//getter setter略….
}
TB_Role.java:
package zjgcmcc.web.entity;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
@Entity
@Table(name="tb_role")
public class TB_Role extends BaseEntity{
private static final long serialVersionUID = 3618646459702991344L;
@Id
@Column(name="r_id")
private String r_id;
@Column(name="r_name")
private String r_name;
@ManyToOne(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST})
@JoinColumn(name="dept_id",unique=true)
private TB_Dept r_dept;
//getter setter略….
}
TB_User.java:
package zjgcmcc.web.entity;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="tb_user")
public class TB_User extends BaseEntity {
private static final long serialVersionUID = 7665797019787902828L;
@Id
@Column(name="u_id")
private String u_id;
@Column(name="u_name")
private String u_name;
//tb_user与tb_dept的多对多关系
@ManyToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST})
@JoinTable(
name="tb_user_role",
joinColumns=@JoinColumn(name="user_id",referencedColumnName="u_id"),
inverseJoinColumns=@JoinColumn(name="role_id",referencedColumnName="r_id")
)
private List<TB_Role> u_roles=new ArrayList<TB_Role>();
@Column(name="u_phone")
private String u_phone;
@Column(name="u_passwd")
private String u_passwd;
//getter setter略….
}
红字部分在配置的时候容易被忽略或配置错误,具体为何配置尚未研究,有达人了解欢迎指点一二 。