JPA 中的二个问题,请教下 EntityManager 为什么为空。我用的是JDK,Tomcat6 Spring JPA

时间:2022-12-24 17:26:59
1.  在DAO 中注入 
     @PersistenceContext(unitName = "jpaDemo")
private EntityManager em;
    我在用 save() 时,em 的值为空。为什么没有注册进来。 EntityManager em;
        @Override
@Transactional(readOnly = false)
public void save(User role) {
em.persist(role);
}

 DAO 中的代码:
 import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;

import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import com.east.jpa.demo.dao.IDAO;
import com.east.jpa.demo.entity.Role;
import com.east.jpa.demo.entity.User;

public class UserDAO extends JpaDaoSupport implements IDAO {

        @PersistenceContext(unitName = "jpaDemo")
private EntityManager em;

@Override
@Transactional(readOnly = false)
public void save(User role) {
em.persist(role);
}

}

-----applicationContext.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/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
xmlns:tx="http://www.springframework.org/schema/tx">


<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="jpaDemo" />
</bean>

<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

<!-- UserDAO -->
<bean id="userDao" class="com.east.jpa.demo.dao.impl.UserDAO">
<property name="entityManagerFactory"
ref="entityManagerFactory">
</property>

</bean>

</beans>
-------------------------------------------------------------------------

----------------------------persistence.xml----------------------------
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="jpaDemo" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.east.jpa.demo.entity.User</class>
<class>com.east.jpa.demo.entity.Role</class>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.Oracle9Dialect" />
<property name="hibernate.connection.driver_class"
value="oracle.jdbc.OracleDriver" />
<property name="hibernate.connection.username" value="East" />
<property name="hibernate.connection.password" value="East" />
<property name="hibernate.connection.url"
value="jdbc:oracle:thin:@127.0.0.1:1521:East" />
<property name="hibernate.max_fetch_depth" value="1" />
<!-- 
<property name="hibernate.hbm2ddl.auto" value="create" />
-->
<!-- 调整JDBC抓取数量的大小: Statement.setFetchSize() -->
<property name="hibernate.jdbc.fetch_size" value="18" />
<!-- 调整JDBC批量更新数量 -->
<property name="hibernate.jdbc.batch_size" value="10" />
<!-- 显示最终执行的SQL  -->
<property name="hibernate.show_sql" value="true" />
<!-- 格式化显示的SQL -->
<property name="hibernate.format_sql" value="true" />

<!-- 配置JTA 事务信息 -->
<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.JTATransactionFactory" />
                        
 我使用这个,就在Tomcat 启动时出错:
Caused by: org.hibernate.TransactionException: Could not find UserTransaction in JNDI: 
at org.hibernate.transaction.JTATransaction.<init>(JTATransaction.java:64)
at org.hibernate.transaction.JTATransactionFactory.createTransaction(JTATransactionFactory.java:57)
at org.hibernate.jdbc.JDBCContext.getTransaction(JDBCContext.java:193)
at org.hibernate.impl.SessionImpl.getTransaction(SessionImpl.java:1315)
at org.hibernate.ejb.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:453)
... 47 more
Caused by: javax.naming.NamingException: Cannot create resource instance

<property    
name="hibernate.transaction.flush_before_completion" value="true" />
<property name="hibernate.transaction.auto_close_session"
value="true" />
</properties>
</persistence-unit>

</persistence>
-----------------------------------------------------------------------------------
--后面我使用了一个类,但是这个类加上去启动没有出错,------org.hibernate.transaction.JDBCTransactionFactory-------
但是在
@Override
@Transactional(readOnly = false)   这个去了,不会有错,但是没有将数据保存到数据库
public void save(User role) {
em.persist(role);
}


2.  方法中带上@Transactional(readOnly = false)这个,用   org.hibernate.transaction.JDBCTransactionFactory
出错。
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
Caused by: java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
at org.hibernate.ejb.AbstractEntityManagerImpl.getTransaction(AbstractEntityManagerImpl.java:317)
at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:70)
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:326)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:350)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy14.save(Unknown Source)
     
     问题1. 为什么em 为空
            2。 怎么配置 persistence.xml  与applicationContext.xml文件,使的程序中能用JTA事务。

    

15 个解决方案

#1


JTA需要transactionManager,你没有定义transactionManager

因为这个没设好,所以entityManager没法启动

把JTA换成LOCAL应该就工作了

#2


JTA的设置需要用JNDI

#3


或者在spring里设置
<bean id="transactionManager" 
 class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="userTransaction">
        <bean class="org.springframework.transaction.jta.JotmFactoryBean"/>
    </property>
</bean>

#4


<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

这个不是设置了事务吗?

#5


有没有一个配置好的,applicationContext.xml与persistence.xml文件,发上来看看。

#6


用JNDI的话,可以如下:
<bean id="transactionManager" 
 class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager">
        <bean class="org.springframework.jndi.JndiObjectFactoryBean">
             <property name="resourceRef" value="true" />
             <property name="jndiName" value="TransactionManager" />
             <property name="expectedType" 
               value="javax.transaction.TransactionManager" />
        </bean>
    </property>
</bean>

#7


或者在applicationContext.xml里面加:
<tx:jta-transaction-manager/>

可以自动找JTA transactoin-manager

#8


强大!  
学习是必须地!
回帖是刚刚地!

#9


用了6楼的方式 ,怎么出错了
org.hibernate.HibernateException: TransactionFactory class not found: org.hibernate.transaction.JTransactionFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:737)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:121)
at javax.persistence.Persistence.createFactory(Persistence.java:171)
... 39 more
Caused by: org.hibernate.HibernateException: TransactionFactory class not found: org.hibernate.transaction.JTransactionFactory

#10


有没有一个配置好的,applicationContext.xml与persistence.xml文件,发上来看看。

#11


 <persistence-unit name="test">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!--<jar-file>WEB-INF/classes</jar-file>
        <jar-file>WEB-INF/lib/pqm-generated.jar</jar-file>
        --><properties>
            <!--<property name="hibernate.ejb.cfgfile" value="/hibernate.cfg.xml"/>-->
            <property name="hibernate.archive.autodetection" value="class" />
            <!-- 
            <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
            -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
            
        </properties>
    </persistence-unit>

#12


Tomcat6不支持EJB啊,楼主

#13


最终解决方案:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/beans http://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/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<!-- JPA 配置信息 -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 持久化单元信息 value 要与persistence 中的unitName 要一致 -->
<!-- 配置数据源 -->
<property name="persistenceUnitName" value="east" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!-- 数据库方式是ORACLE 或SQL SERVER -->
<property name="database" value="ORACLE"></property>
<!-- 是否显示sql 语句 -->
<property name="showSql" value="true"></property>
</bean>
</property>
</bean>

<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
</bean>

<!--JPA Transaction -->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<!-- 支持@Transaction 方式 -->
<tx:annotation-driven proxy-target-class="true"
transaction-manager="transactionManager" />

<!-- PersisteContext 注册方式-->
<context:spring-configured />
<context:annotation-config />
</beans>

-------------------------------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="east">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!--<jar-file>WEB-INF/classes</jar-file>
<jar-file>WEB-INF/lib/test-generated.jar</jar-file>
-->
<properties>
<!--<property name="hibernate.ejb.cfgfile" value="/hibernate.cfg.xml"/>-->
<property name="hibernate.archive.autodetection"
value="class" />
<!-- 
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
-->
<property name="hibernate.dialect"
value="org.hibernate.dialect.Oracle10gDialect" />

</properties>
</persistence-unit>
</persistence>

/**
 * 数据库持久化的实现<br>
 * ProjectName:JPA_Demo <br>
 * Class Name:IDAOImpl.java<br>
 * Class Description:<br>
 * Author:East 271536394 <br>
 * Create Time:Aug 29, 2010 7:41:55 PM<br>
 * 
 * @version 1.0
 */
public class IDAOImpl implements IDAO {
/* 自动注册 */
@PersistenceContext
EntityManager em;

@Override
public <T> void create(Collection<Class<T>> entitys) throws Exception {
for (Class<T> entity : entitys) {
create(entity);
}
}

public EntityManager getEm() {
return em;
}

private static final Logger logger = Logger.getLogger(IDAOImpl.class);

@Override
public <T> int count(Class<T> entity) throws Exception {
return findAll(entity).size();
}

@Override
@Transactional(readOnly = false)
public <T> void create(T entity) throws Exception {
if (em == null) {
logger.error("init EntityManager is error");
}
getEm().persist(entity);

}
}




#14


你用 Tomcat, Spring, Hibernate 那说明处于 J2SE 环境中,在 J2SE 环境中是不能使用 JTA 事务的。

JTA 事务必须在 J2EE 环境中,也就是在 J2EE 应用服务器中才能够使用。

#15


Tomcat  Spring Hibernate 说明在 j2se   

我现在就是在j2ee上呀

#1


JTA需要transactionManager,你没有定义transactionManager

因为这个没设好,所以entityManager没法启动

把JTA换成LOCAL应该就工作了

#2


JTA的设置需要用JNDI

#3


或者在spring里设置
<bean id="transactionManager" 
 class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="userTransaction">
        <bean class="org.springframework.transaction.jta.JotmFactoryBean"/>
    </property>
</bean>

#4


<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

这个不是设置了事务吗?

#5


有没有一个配置好的,applicationContext.xml与persistence.xml文件,发上来看看。

#6


用JNDI的话,可以如下:
<bean id="transactionManager" 
 class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager">
        <bean class="org.springframework.jndi.JndiObjectFactoryBean">
             <property name="resourceRef" value="true" />
             <property name="jndiName" value="TransactionManager" />
             <property name="expectedType" 
               value="javax.transaction.TransactionManager" />
        </bean>
    </property>
</bean>

#7


或者在applicationContext.xml里面加:
<tx:jta-transaction-manager/>

可以自动找JTA transactoin-manager

#8


强大!  
学习是必须地!
回帖是刚刚地!

#9


用了6楼的方式 ,怎么出错了
org.hibernate.HibernateException: TransactionFactory class not found: org.hibernate.transaction.JTransactionFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:737)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:121)
at javax.persistence.Persistence.createFactory(Persistence.java:171)
... 39 more
Caused by: org.hibernate.HibernateException: TransactionFactory class not found: org.hibernate.transaction.JTransactionFactory

#10


有没有一个配置好的,applicationContext.xml与persistence.xml文件,发上来看看。

#11


 <persistence-unit name="test">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!--<jar-file>WEB-INF/classes</jar-file>
        <jar-file>WEB-INF/lib/pqm-generated.jar</jar-file>
        --><properties>
            <!--<property name="hibernate.ejb.cfgfile" value="/hibernate.cfg.xml"/>-->
            <property name="hibernate.archive.autodetection" value="class" />
            <!-- 
            <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
            -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
            
        </properties>
    </persistence-unit>

#12


Tomcat6不支持EJB啊,楼主

#13


最终解决方案:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/beans http://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/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<!-- JPA 配置信息 -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 持久化单元信息 value 要与persistence 中的unitName 要一致 -->
<!-- 配置数据源 -->
<property name="persistenceUnitName" value="east" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!-- 数据库方式是ORACLE 或SQL SERVER -->
<property name="database" value="ORACLE"></property>
<!-- 是否显示sql 语句 -->
<property name="showSql" value="true"></property>
</bean>
</property>
</bean>

<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
</bean>

<!--JPA Transaction -->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<!-- 支持@Transaction 方式 -->
<tx:annotation-driven proxy-target-class="true"
transaction-manager="transactionManager" />

<!-- PersisteContext 注册方式-->
<context:spring-configured />
<context:annotation-config />
</beans>

-------------------------------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="east">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!--<jar-file>WEB-INF/classes</jar-file>
<jar-file>WEB-INF/lib/test-generated.jar</jar-file>
-->
<properties>
<!--<property name="hibernate.ejb.cfgfile" value="/hibernate.cfg.xml"/>-->
<property name="hibernate.archive.autodetection"
value="class" />
<!-- 
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
-->
<property name="hibernate.dialect"
value="org.hibernate.dialect.Oracle10gDialect" />

</properties>
</persistence-unit>
</persistence>

/**
 * 数据库持久化的实现<br>
 * ProjectName:JPA_Demo <br>
 * Class Name:IDAOImpl.java<br>
 * Class Description:<br>
 * Author:East 271536394 <br>
 * Create Time:Aug 29, 2010 7:41:55 PM<br>
 * 
 * @version 1.0
 */
public class IDAOImpl implements IDAO {
/* 自动注册 */
@PersistenceContext
EntityManager em;

@Override
public <T> void create(Collection<Class<T>> entitys) throws Exception {
for (Class<T> entity : entitys) {
create(entity);
}
}

public EntityManager getEm() {
return em;
}

private static final Logger logger = Logger.getLogger(IDAOImpl.class);

@Override
public <T> int count(Class<T> entity) throws Exception {
return findAll(entity).size();
}

@Override
@Transactional(readOnly = false)
public <T> void create(T entity) throws Exception {
if (em == null) {
logger.error("init EntityManager is error");
}
getEm().persist(entity);

}
}




#14


你用 Tomcat, Spring, Hibernate 那说明处于 J2SE 环境中,在 J2SE 环境中是不能使用 JTA 事务的。

JTA 事务必须在 J2EE 环境中,也就是在 J2EE 应用服务器中才能够使用。

#15


Tomcat  Spring Hibernate 说明在 j2se   

我现在就是在j2ee上呀