被spring和hibernate4逼疯

yongzhong 发布于 2013/11/03 15:17
阅读 16K+
收藏 3

spring3.1整合hibernate4,事务都配置上了的,但getCurrentSession()仍然获得不到

以下是各配置

web.xml

<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>

	<!-- Filter 定义 -->
	<!-- Character Encoding filter -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- Spring MVC Servlet -->
	<servlet>
		<servlet-name>springServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<!-- open session filter -->
	<filter>
		<filter-name>openSessionInViewFilter</filter-name>
		<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
		<init-param>
			<param-name>singleSession</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>

	<!-- session超时定义,单位为分钟 -->
	<session-config>
		<session-timeout>20</session-timeout>
	</session-config>

	<!-- Define pages of error -->
	<error-page>
		<exception-type>java.lang.Throwable</exception-type>
		<location>/WEB-INF/error/500.jsp</location>
	</error-page>
	<error-page>
		<error-code>500</error-code>
		<location>/WEB-INF/error/500.jsp</location>
	</error-page>
	<error-page>
		<error-code>404</error-code>
		<location>/WEB-INF/error/404.jsp</location>
	</error-page>
applicationContext.xml
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
		<property name="driverClass">
			<value>com.mysql.jdbc.Driver</value>
		</property>
		<property name="jdbcUrl">
			<value>jdbc:mysql://localhost:3306/pannote</value>
		</property>
		<property name="username">
			<value>root</value>
		</property>
		<property name="password">
			<value>1234</value>
		</property>

		<!-- Max connection numbers in every partition -->
		<property name="maxConnectionsPerPartition" value="15" />
		<!-- Min connection numbers in every partition -->
		<property name="minConnectionsPerPartition" value="1" />
		<!-- Partition numbers,default as 2,min as 1,recommend 3-4,depends on -->
		<property name="partitionCount" value="4" />
		<!-- Everytime the numbers of connection requirement,default as 2 -->
		<property name="acquireIncrement" value="2" />
		<!-- Value of the cache prepared statements,default as 0 -->
		<property name="statementsCacheSize" value="0" />
		<!-- The number of release connection assistant process by every partition -->
		<!-- Default as 3.Your performance will be affected by excessive assistant process unless you need to do a lot work in one connection -->
		<property name="releaseHelperThreads" value="3" />
	</bean>

	<!--Define the sessionFactory of hibernate4 -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.SybaseDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
			</props>
		</property>
		<!-- <property name="mappingResources"> <list> <value>my/hy/pannote/entity/Message.hbm.xml</value> </list> </property> -->
	</bean>

	<!-- 事务管理器配置,单数据源事务 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="save*" propagation="REQUIRED" read-only="false" />
			<tx:method name="add*" propagation="REQUIRED" read-only="false" />
			<tx:method name="create*" propagation="REQUIRED" read-only="false" />
			<tx:method name="insert*" propagation="REQUIRED" read-only="false" />
			<tx:method name="turn*" propagation="REQUIRED" read-only="false" />
			<tx:method name="*" read-only="true" />
		</tx:attributes>
	</tx:advice>
	<aop:config proxy-target-class="true">
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* my.hy.pannote..*.*(..))" />
	</aop:config>

spring-mvc.xml

<context:component-scan base-package="my.hy.pannote" >
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
	
	<mvc:annotation-driven />

	<mvc:default-servlet-handler />

	<!-- 定义首页 -->
	<mvc:view-controller path="/" view-name="redirect:/index" />

	<!-- 定义JSP -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
	</bean>
controller
@RequestMapping(value = "/addMessage", method = RequestMethod.POST)
	public String addMessage(Message message, RedirectAttributes redirectAttributes) {
		try {
			messageService.add(message);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("信息添加错误");
			redirectAttributes.addFlashAttribute("error", "系统错误,请稍后再试");
		}
		return "redirect:/index";
	}
service
@Component
@Transactional
public class MessageService {

	@Autowired
	private TestDAO testDAO;

	public void add(Message entity) {
		testDAO.save(entity);
	}

}
dao
@Component
public class TestDAO {
	
	@Autowired
	private SessionFactory sessionFactory;

	public void save(Message entity) {
		System.out.println("-----"+sessionFactory);
		System.out.println("======"+sessionFactory.getCurrentSession());
		sessionFactory.getCurrentSession().saveOrUpdate(entity);
	}

 
 
 
 
} 
-----org.hibernate.internal.SessionFactoryImpl@de82eff
org.hibernate.HibernateException: No Session found for current thread
 at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
 at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1041)
 at my.hy.pannote.dao.TestDAO.save(TestDAO.java:18)
 at my.hy.pannote.service.MessageService.add(MessageService.java:23)
 at my.hy.pannote.base.UserBaseController.addMessage(UserBaseController.java:50)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)


 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
 at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
 at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)


 at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
 at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
 at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)


 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
 at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)


 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)


 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
 at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
 at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)


 at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
 at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
 at java.lang.Thread.run(Thread.java:722)

加载中
0
yongzhong
yongzhong

终于弄好了...原因是openSessionInViewFilter没有过滤请求

根据http://stackoverflow.com/questions/15939932/hibernateexception-no-session-found-for-current-thread-when-calling-service-from

社区里也有这个问题,翻出去了才搜到...http://www.oschina.net/question/659963_87447

我修改了web.xml如下配置

<!-- open session filter -->
	<filter>
		<filter-name>openSessionInViewFilter</filter-name>
		<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
		<init-param>
			<param-name>sessionFactoryBeanName</param-name>
			<param-value>sessionFactory</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>openSessionInViewFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
hantsy
hantsy
自己看 openSessionInViewFilter 代码吧,,,这个 openSessionInViewFilter 是可选的 不是一定要使用的。你的问题是, hibernate.current_session_context_class 设置和事务配置的问题。
yongzhong
yongzhong
回复 @hantsy : LazyInitialiaztionException是映射关联的错误,延迟加载是对于数据库操作时候的问题,而我这里并没有进行数据库操作,而只是getCurrentSession(),解决这个问题的关键在于没有过滤请求
hantsy
hantsy
这个问题和 OpenSessionInView Filter 一点关系都没有,这个Filter 主要是解决Web 层的Hibernate的 LazyInitialiaztionException,,,实际是它是一种反模式,不提倡使用。
0
hantsy
hantsy
https://github.com/hantsy/spring-sandbox/wiki/use-native-hiberante4-api
yongzhong
yongzhong
回复 @hantsy : 数据库连接没有问题,而且报错并不是在持久化的时候出现的,而是在getCurrentSession()上
hantsy
hantsy
你的自己的问题,首先要确定你的数据库连接配置是否可以连通。。。这是最基本的。 我的代码全部是有测试通过的,你可以clone代码出来测试。
yongzhong
yongzhong
没有效果..
0
klaus_
klaus_
service 我们一般用@Service dao用@repository 另外,sessionFactory有值么?
yongzhong
yongzhong
几个注解都试过,没有效果 sessionFactory能获得
0
人贩子一枚
人贩子一枚
把异常栈贴出来
yongzhong
yongzhong
回复 @人贩子一枚 : SybaseDialect修改过来了,不是这个的问题.我尝试过把org.springframework.orm.hibernate4.SpringSessionContext换成了hibernate3的thread,这时获得session正常,但是事务没有开启
人贩子一枚
人贩子一枚
应该是配置文件某个节点错了,找找其他例子一行行查查肯定能解决的。我注意到你连的是mysql但是用的是SybaseDialect,不确定是不是这个问题,2年没碰Hibernate了,现在都出4了
0
紫电清霜
紫电清霜
SSH,真心不喜欢
紫电清霜
紫电清霜
回复 @颜_ : 恩恩,试试jfinal吧,挺给力的!!!
JFinal
JFinal
回复 @颜_ : 有了下面这几个就打完收工了:http://my.oschina.net/myaniu/blog/137206 http://my.oschina.net/myaniu/blog/137198 http://my.oschina.net/myaniu/blog/137205
yongzhong
yongzhong
回复 @JFinal : 其实有用过的,只是我对于JFINAL的安全的配置和框架的熟悉程度不及spring,所以暂时没有用在手头上的东西
JFinal
JFinal
回复 @颜_ : 试试 @JFinal
yongzhong
yongzhong
现在只用了spring和hibernate,以后再尝试把hibernate换掉
0
rabbitgg
rabbitgg
读取数据也需要 REQUIRED事物的
0
筱龙缘
筱龙缘
 <tx:method  name="*"  read-only="true"  />   改掉  必须要有事务
0
宏哥
宏哥

用hibernate -- 证明你已经疯了

而不是hibernate把你逼疯的 

yongzhong
yongzhong
还在治疗当中
hantsy
hantsy
疯人疯语
0
小白小霸王
小白小霸王
我来看看 有没有说jfinal 一般这个时候肯定有人推荐
0
请叫我小V
请叫我小V
出现了和你一样的情况,我也快被逼疯了。刚刚试了一下你的解决方案,果然可以。十分感谢(我还特地因为这个问题在CSDN上发了一个很长的帖子)
返回顶部
顶部