项目使用Hibernate(JPA),Spring和Maven。我的实体和DAO在单独的JAR中。
pom.xml:
<project ...> ... <artifactId>database</artifactId> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>3.5.4-Final</version> </dependency> </dependencies> </project>
DAO:
public class AbstractDAO<T extends BaseEntity> implements GenericDAO<T> { private final Class<T> persistentClass; private EntityManager entityManager; public AbstractDAO(Class<T> entityClass) { super(); this.persistentClass = entityClass; } @PersistenceContext public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } public EntityManager getEntityManager() { return entityManager; } ... public void fooBar() { //Exception from this line Session session = getEntityManager().unwrap(Session.class); ... } .... }
我有一个使用Spring的模块。
<project ...> ... <artifactId>api</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> .... </dependencies> ... </project>
AppContext.xml:
<bean id="authService" scope="singleton" class="com.test.management.AuthServiceImpl" /> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" name="EntityManagerFactory"> <property name="persistenceUnitName" value="default"></property> <property name="dataSource" ref="dataSource"></property> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="true" /> <property name="generateDdl" value="true" /> <property name="databasePlatform" value="${db.dialect}" /> </bean> </property> </bean> <!-- Values are defined in db.properties --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${db.driver}" /> <property name="url" value="${db.url}" /> <property name="username" value="${db.username}" /> <property name="password" value="${db.password}" /> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" name="TransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"></property> </bean> <tx:annotation-driven /> <bean id="userDAO" scope="singleton" class="com.test.database.dao.impl.UserDAOImpl"> </bean> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> </beans>
服务:
public class AuthServiceImpl implements AuthService { @Autowired private UserDAO userDAO; @Override public void authorization() { userDAO.fooBar(); } }
当我尝试从EntityManager中获取会话时,遇到以下异常:
java.lang.IllegalStateException: No transactional EntityManager available at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:223) at $Proxy121.unwrap(Unknown Source)
你必须在方法周围加上@Transactional批注:
@Transactional public void fooBar() { //Exception from this line Session session = getEntityManager().unwrap(Session.class); ... }
并在spring的xml配置文件中使用以下声明启用spring @Transactional处理(txManager是你的管理器的ID)。
<tx:annotation-driven transaction-manager="txManager" />