我试图在Eclipse中使用Spring 4,Primefaces 5和Hibernate JPA创建一个项目,运行Wildfly 8.0。我的项目现在运行正常。唯一的问题是@Transactional注释不起作用。我试过这个(就像我在另一个SO问题中看到的那样)并且它有效(这在我的DAO中):
@Repository(value="empleadoDAO")
public class EmpleadoDAO {
@Resource(name="myEmf")
private EntityManagerFactory em;
private EntityManager emf;
public boolean insertarEmpleado(Empleado emp) {
boolean res = true;
emf = em.createEntityManager();
emf.getTransaction().begin();
emf.persist(emp);
emf.getTransaction().commit();
return res;
}
}
如果我这样做,它可以工作,但是如果我在我的DAO或我的服务中使用@Transactional注释,要么使用javax.transaction中的注释或使用springframework注释它不起作用。它没有给我一个例外或者什么都没有,但如果我查看数据库它不会插入任何东西(我使用PostgreSQL 9.3)。
此外,目前我正在将EntityManagerFactory注入到我的DAO中而不只是注入EntityManager。我尝试使用@PersistenceContext注入EntityManager(unitName =" myPersistenceUnit")但它给了我这个错误:
JBAS016069: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named myPersistenceUnit in deployment sprisf2.war
这是我的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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:spring-configured />
<context:annotation-config />
<task:annotation-driven />
<context:component-scan base-package="com.saplic.sprisf.daos" />
<context:component-scan base-package="com.saplic.sprisf.managedbeans" />
<context:component-scan base-package="com.saplic.sprisf.services" />
<context:component-scan base-package="com.saplic.sprisf.entities" />
<mvc:annotation-driven />
<bean id="myEmf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dbDs"></property>
<property name="persistenceUnitName" value="myPersistenceUnit" />
<property name="packagesToScan" value="com.saplic.sprisf.entities" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf" />
<property name="dataSource" ref="dbDs" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<jee:jndi-lookup id="dbDs" jndi-name="java:jboss/datasources/postgreDS"></jee:jndi-lookup>
<mvc:resources location="/resources/" mapping="/static/**" />
</beans>
以前它在没有persistence.xml文件的情况下启动并在代码中提交事务,但之后我决定创建一个尝试使用@PersistenceContext注入EntityManager,这里是我的persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0">
<persistence-unit name="myPersistenceUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<!-- property name="hibernate.max_fetch_depth" value="3" /-->
<!-- property name="hibernate.order_updates" value="true" /-->
<property name="hibernate.default_schema" value="public" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />
<property name="jboss.entity.manager.factory.jndi.name" value="java:jboss/datasources/postgreDS" />
</properties>
</persistence-unit>
</persistence>
我在LocalContainerEntityManagerFactoryBean中使用此属性引用了此persistence.xml:
<property name="persistenceXmlLocation" value="/META-INF/persistence.xml" />
至少我想在我的服务中使用@Transactional来保存我的数据,而不必通过代码启动和提交事务,如果我可以注入EntityManager而不是EntityManagerFactory,那将会很棒。
[编辑]这是我的文件EmpleadoManagedBean和EmpleadoService,我从中调用DAO方法进行插入:
@Component(value="empleadoMB")
@ManagedBean(name="empleadoMB")
@ConversationScoped
public class EmpleadoManagedBean implements Serializable {
@Resource(name="empleadoService")
private EmpleadoService empleadoService;
private Empleado instance = new Empleado();
public String addEmpleado() {
empleadoService.insertarEmpleado(instance);
return "SUCCESS";
}
}
我确信实例对象具有调用insertarEmpleado之前的必要数据。这是我的服务类:
@Service("empleadoService")
@Transactional
public class EmpleadoService {
@Resource(name="empleadoDAO")
private EmpleadoDAO empleadoDAO;
@Transactional
public void insertarEmpleado(Empleado emp) {
empleadoDAO.insertarEmpleado(emp);
}
}
[编辑]通过查看一些示例,我看到有些人只是声明然后是一个名为transactionManager的bean,我将bean的名称更改为txManager并且它给我一个错误,表明没有bean id transactionManager,所以我认为它注入了Services,但由于某种原因,注释不起作用。
答案 0 :(得分:0)
这不是一个真正的答案,但即使我觉得有点受限制,它对我也有用。我看到eclipse中生成的Wildfly日志,我看到了:
14:58:22,465 INFO [org.jboss.as.jpa] (MSC service thread 1-4) JBAS011401: Read persistence.xml for sprisf2
14:58:22,665 INFO [org.jboss.as.jpa] (ServerService Thread Pool -- 77) JBAS011409: Starting Persistence Unit (phase 1 of 2) Service 'sprisf2.war#sprisf2'
14:58:22,674 INFO [org.hibernate.jpa.internal.util.LogHelper] (ServerService Thread Pool -- 77) HHH000204: Processing PersistenceUnitInfo [
name: sprisf2
...]
14:58:22,739 INFO [org.hibernate.Version] (ServerService Thread Pool -- 77) HHH000412: Hibernate Core {4.3.5.Final}
14:58:22,741 INFO [org.hibernate.cfg.Environment] (ServerService Thread Pool -- 77) HHH000206: hibernate.properties not found
14:58:22,742 INFO [org.hibernate.cfg.Environment] (ServerService Thread Pool -- 77) HHH000021: Bytecode provider name : javassist
14:58:23,410 INFO [org.jboss.as.jpa] (ServerService Thread Pool -- 77) JBAS011409: Starting Persistence Unit (phase 2 of 2) Service 'sprisf2.war#sprisf2'
14:58:25,619 INFO [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] (MSC service thread 1-3) Building JPA container EntityManagerFactory for persistence unit 'sprisf2'
14:58:25,619 WARN [org.hibernate.ejb.HibernatePersistence] (MSC service thread 1-3) HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
14:58:25,620 INFO [org.hibernate.jpa.internal.util.LogHelper] (MSC service thread 1-3) HHH000204: Processing PersistenceUnitInfo [
name: sprisf2
...]
14:58:26,029 INFO [org.hibernate.dialect.Dialect] (MSC service thread 1-3) HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
根据LocalContainerEntityManagerFactoryBean文档,它使用persistence.xml中的信息生成PersistenceInfoUnit,或者如果不使用jpaProperties值定义它,则可以使用此bean将EntityManagers注入DAO。正如您在日志中看到的,它生成一个名为sprisf2(我的项目名称)的PersistenceUnitInfo,当我将其用作持久性单元名称时:
@PersistenceContext(unitName="sprisf2")
private EntityManager entityManager;
创建一个空的persistence.xml后,它工作了!!不幸的是,即使我使用不同的名称指定persistenceUnitName,我似乎也无法更改PersistenceUnitInfo名称。
有人知道为什么我不能改名字?为什么我需要有一个空的persistence.xml才能工作?