Spring+JPA整合问题 请参考我的配置文件http://www.java2000.net/viewthread.jsp?tid=49@Transactional public class MyService { @PersistenceContext private EntityManager em; } 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这个是我的配置文件:applicationContext.xml.我们应该配置都差不多的,关键是我注入EntityManagerFactory 正常,注入EntityManager 就发生Session is closed.我怀疑是注入了一个关闭的Session,可能是哪里配置错误.----------------------------------------------------<?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="vipcardPU" /> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- JPA annotations bean post processor --> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /></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="vipcardPU" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>com.sincere.bean.SLink</class> <class>com.sincere.bean.Personnel</class> <class>com.sincere.bean.MenuAction</class> <class>com.sincere.bean.Datadict</class> <class>com.sincere.bean.Groupmanage</class> <properties> <property name="hibernate.connection.driver_class" value="net.sourceforge.jtds.jdbc.Driver" /> <property name="hibernate.connection.url" value="jdbc:jtds:sqlserver://127.0.0.1:1433/sincere" /> <property name="hibernate.connection.username" value="sa" /> <property name="hibernate.connection.password" value="sin3002" /> <property name="hibernate.c3p0.max_size" value="10" /> <property name="hibernate.c3p0.min_size" value="2" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.c3p0.timeout" value="1800" /> <property name="hibernate.cache.use_query_cache" value="2" /> <!-- <property name="hibernate.connection.autocommit" value="true" /> --> <property name="hibernate.show_sql" value="true" /> <!-- <property name="hibernate.format_sql" value="true" /> --> </properties> </persistence-unit></persistence> 1 看1楼的代码,你是不是少了@Transactional 2 还有,你的applicationContext.xml里面得有<bean id="MyService" class=""/>3 BeanFactory 采用 try { beanFactory = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" }); } catch (Exception ex) { ex.printStackTrace(); }拿到4 beanFactory.getBean(beanName);// 这个没啥说的 我的论坛采用JPA书写的,还不行,你下载一个自己看看吧!最基本功能能用,但不完善。只完成了最简单的功能http://www.java2000.net/forumdisplay.jsp?fid=15 多谢java2000_net ,问题解决了,在类文件头部少了一个@Transactional 注释.真是粗心啊.不过,我在Spring参考开发手册上没有看到这个注释的... 铁一个我的附件的服务类package net.java2000.forum.service;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;import net.java2000.forum.Attachment;import net.java2000.forum.util.AttachmentFile;import net.java2000.tools.StrTools;import org.springframework.transaction.annotation.Transactional;@Transactionalpublic class AttachmentService { @PersistenceContext private EntityManager em; public Attachment get(long id) { Attachment attachment = em.find(Attachment.class, id); return attachment; } public Attachment save(Attachment attachment) { if (attachment.getId() <= 0) { return insert(attachment); } return update(attachment); } private Attachment insert(Attachment attachment) { em.persist(attachment); return attachment; } private Attachment update(Attachment attachment) { attachment = em.merge(attachment); return attachment; }} @Transactional是JPA提供的,等同于以前的 CMP 楼上二位,我现在也在尝试使用 Spring + JPA + Hibernate 的持久化方案。 我遇到的问题和楼主的很相似,但有些不同的是,楼主出现的问题只有当我调用 EntityManager 的 createQuery 方法时会出现。而如果直接通过 EntityManager 的 find 方法获取实体对象,则没有问题。 另外,按说采用 Spring 管理的实体管理器进行持久化操作不需要手动进行事务的开始和提交,这点在老紫竹的代码里也很表现出来了。但在我进行持久化操作时,如果直接调用 persist 方法,而不手动进行事务操作,则数据根本不会写入数据库。 如果人为调用 EntityManager 的 em.getTransaction().begin() 方法则会抛出这个异常:java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead 另外,我想问一下,在 Spring 下以这种方式使用 JPA 不是一定要在 Java EE 环境下才可以吧?普通的 Tomcat 下,也可以实现?实在是不明白,请各位指教,谢谢!我的主要代码如下: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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://localhost:3306/test</value> </property> <property name="username"> <value></value> </property> <property name="password"> <value></value> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>persistence.xml<?xml version="1.0" encoding="UTF-8"?><persistence version="1.0" 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"> <persistence-unit name="ResumeServicePU" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>cn.edu.cuc.memo.persistences.NewsContent</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.show_sql" value="true"/> </properties></persistence-unit></persistence>尝试的 Java 类import java.util.Calendar;import java.util.UUID;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;import org.springframework.transaction.annotation.Transactional;@Transactionalpublic class Test { @PersistenceContext private EntityManager em = null; public void insertNews() { em.getTransaction().begin(); NewsContent newsContent = new NewsContent(); newsContent.setUuid(UUID.randomUUID().toString()); newsContent.setNewsText("texttext"); newsContent.setNewsUrl("urlurl"); newsContent.setPubDate(Calendar.getInstance().getTime()); newsContent.setTitle("titletitle"); em.persist(newsContent); em.getTransaction().commit(); }} 问题解决了。我是在一个 Web 应用中作上述试验的。而在 Spring-web 环境下,Spring 所有 bean 的装载工作是从默认的 dispatcher-servlet.xml 文件开始的,而我将 JPA 的相关 bean 的配置放在了另外的配置文件中,包括<tx:annotation-driven transaction-manager="transactionManager"/>。正是这个配置没有在 dispatcher-servlet.xml 文件中,导致我的程序在运行的时候,transaction 没有和当前的线程绑定到一起,所以程序提交时实际上没有启动事务,导致了我之前出现的数据不写入等等问题。楼上两位的讨论引起了我对这个配置的注意,谢谢了,呵呵!! 我刚开始学这几个框架 这几天正在做这个的Demo 我刚刚也碰到这个问题了 但是后来仔细看了一下解决了 看过你们的讨论 我就更加明白了 谢谢你们 我现在的问题是:当TomCat启动后能不能更改Spring的数据库连接,如何改?多谢各位帮忙!!! MQ JAVA 实现问题。求帮助 求大神帮我看下是哪里出错 BTrace问题 oracle10g system账户锁定了,怎么解锁啊? AJAX接收XML文档出错! 严重: Invalid path /login was requested web日历,直接把在日历上选中的日期输入到text里面去,有这样的组件吗? 高分求教JSP+hibernate连接数据库稳定性问题,急!! 请教:tx data sources 与 data sources 的区别? mina客户端断线重连问题,困扰好久了,求解啊。。。。 关于tomcat拒绝访问 oc4j是什么以及oc4j如何应用?
我怀疑是注入了一个关闭的Session,可能是哪里配置错误.
----------------------------------------------------
<?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="vipcardPU" />
</bean> <bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- JPA annotations bean post processor -->
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /></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="vipcardPU"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.sincere.bean.SLink</class>
<class>com.sincere.bean.Personnel</class>
<class>com.sincere.bean.MenuAction</class>
<class>com.sincere.bean.Datadict</class>
<class>com.sincere.bean.Groupmanage</class>
<properties>
<property name="hibernate.connection.driver_class"
value="net.sourceforge.jtds.jdbc.Driver" />
<property name="hibernate.connection.url"
value="jdbc:jtds:sqlserver://127.0.0.1:1433/sincere" />
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="sin3002" />
<property name="hibernate.c3p0.max_size" value="10" />
<property name="hibernate.c3p0.min_size" value="2" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.c3p0.timeout" value="1800" />
<property name="hibernate.cache.use_query_cache" value="2" />
<!-- <property name="hibernate.connection.autocommit" value="true" /> -->
<property name="hibernate.show_sql" value="true" />
<!-- <property name="hibernate.format_sql" value="true" /> -->
</properties>
</persistence-unit></persistence>
@Transactional 2 还有,你的applicationContext.xml
里面得有
<bean id="MyService" class=""/>3 BeanFactory 采用
try {
beanFactory = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
} catch (Exception ex) {
ex.printStackTrace();
}拿到
4 beanFactory.getBean(beanName);// 这个没啥说的
最基本功能能用,但不完善。只完成了最简单的功能http://www.java2000.net/forumdisplay.jsp?fid=15
真是粗心啊.
不过,我在Spring参考开发手册上没有看到这个注释的...
package net.java2000.forum.service;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;import net.java2000.forum.Attachment;
import net.java2000.forum.util.AttachmentFile;
import net.java2000.tools.StrTools;import org.springframework.transaction.annotation.Transactional;@Transactional
public class AttachmentService {
@PersistenceContext
private EntityManager em; public Attachment get(long id) {
Attachment attachment = em.find(Attachment.class, id);
return attachment;
} public Attachment save(Attachment attachment) {
if (attachment.getId() <= 0) {
return insert(attachment);
}
return update(attachment);
} private Attachment insert(Attachment attachment) {
em.persist(attachment);
return attachment;
} private Attachment update(Attachment attachment) {
attachment = em.merge(attachment);
return attachment;
}
}
是JPA提供的,等同于以前的 CMP
我遇到的问题和楼主的很相似,但有些不同的是,楼主出现的问题只有当我调用 EntityManager 的 createQuery 方法时会出现。而如果直接通过 EntityManager 的 find 方法获取实体对象,则没有问题。
另外,按说采用 Spring 管理的实体管理器进行持久化操作不需要手动进行事务的开始和提交,这点在老紫竹的代码里也很表现出来了。但在我进行持久化操作时,如果直接调用 persist 方法,而不手动进行事务操作,则数据根本不会写入数据库。
如果人为调用 EntityManager 的 em.getTransaction().begin() 方法则会抛出这个异常:java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
另外,我想问一下,在 Spring 下以这种方式使用 JPA 不是一定要在 Java EE 环境下才可以吧?普通的 Tomcat 下,也可以实现?实在是不明白,请各位指教,谢谢!我的主要代码如下:
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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/test</value>
</property>
<property name="username">
<value></value>
</property>
<property name="password">
<value></value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
persistence.xml<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" 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">
<persistence-unit name="ResumeServicePU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>cn.edu.cuc.memo.persistences.NewsContent</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>尝试的 Java 类import java.util.Calendar;
import java.util.UUID;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;import org.springframework.transaction.annotation.Transactional;@Transactional
public class Test {
@PersistenceContext
private EntityManager em = null;
public void insertNews() {
em.getTransaction().begin();
NewsContent newsContent = new NewsContent();
newsContent.setUuid(UUID.randomUUID().toString());
newsContent.setNewsText("texttext");
newsContent.setNewsUrl("urlurl");
newsContent.setPubDate(Calendar.getInstance().getTime());
newsContent.setTitle("titletitle");
em.persist(newsContent);
em.getTransaction().commit();
}
}
楼上两位的讨论引起了我对这个配置的注意,谢谢了,呵呵!!
这几天正在做这个的Demo
我刚刚也碰到这个问题了 但是后来仔细看了一下解决了
看过你们的讨论 我就更加明白了 谢谢你们
多谢各位帮忙!!!