使用spring和hibernate开发了一个Web应用程序。这是一个非常庞大的应用程序,我也必须从控制器外部获得一些服务。为此,我使用xmlclasspathcontext同时获取bean。
目前我正在使用threadlocal和opensession。到目前为止我没有问题,除了在更新某些东西时读取旧数据。我知道这是因为threadlocal保持当前会话。
我想学的是,İF我删除threadlocal并使用öpensession和close会话这是一个好方法吗? 因为我不能同时使用控制器和getbeans的getcurrentsession。 İam没有在xmXML get bean端找到错误的会话。有没有办法在两边得到getcurrentsession?或者我是否必须使用开放和关闭会话方法?什么İF我不关闭每个opwnsession?
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.yupsoft.grid" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/grid" />
<property name="username" value="myuser" />
<property name="password" value="mypass" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.yupsoft.yupsoft.model.LanguageTextParameter</value>
<value>com.yupsoft.yupsoft.model.LoginHistory</value>
<value>com.yupsoft.yupsoft.model.Session</value>
<value>com.yupsoft.yupsoft.model.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!--
<prop key="hibernate.connection.autocommit">false</prop>
-->
<prop key="hibernate.connection.charSet">utf8</prop>
<prop key="hibernate.connection.characterEncoding">utf8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.autoReconnect">true</prop>
<prop key="current_session_context_class">thread</prop>
<prop key="hibernate.connection.pool_size">1</prop>
<prop key="hibernate.c3p0.min_size">10</prop>
<prop key="hibernate.c3p0.max_size">100</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.idle_test_period">30</prop>
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.preferredTestQuery">select 1;</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="hibernate.connection.isolation">8</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
这是我收到请求的Controller类
@Controller
public class UserController {
@Autowired
private UserService userService;
@Autowired
private LoginHistoryService loginHistoryService;
@RequestMapping(value = "/loginAttempt", method = RequestMethod.POST)
public @ResponseBody
String loginAttempt(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
String password = request.getParameter("password");
User user = userService.getByUserNameAndPassword(userName, password);
if (user != null) {
if (user.isActive()) {
LoginHistory loginHistory = new LoginHistory();
loginHistory.setCreated(new Date());
loginHistory.setIpAddress(request.getRemoteAddr());
loginHistory.setSessionId(request.getSession().getId());
loginHistory.setAccountVerified(Boolean.TRUE);
loginHistory.setUser(user);
boolean loginHistoryCreated = loginHistoryService.create(loginHistory);
if (loginHistoryCreated) {
return "ok";
} else {
//Error
return "err";
}
} else {
return "err";
}
}
return "ok";
}
}
这是服务层
@Service("loginHistoryService")
@Transactional(propagation = Propagation.REQUIRED,readOnly = true,isolation = Isolation.SERIALIZABLE) public class LoginHistoryServiceImpl extends GenericServiceImpl实现了LoginHistoryService {
@Autowired
private LoginHistoryDAO loginHistoryDAO;
public LoginHistoryDAO getLoginHistoryDAO() {
return loginHistoryDAO;
}
public void setLoginHistoryDAO(LoginHistoryDAO loginHistoryDAO) {
this.loginHistoryDAO = loginHistoryDAO;
setGenericDAO(loginHistoryDAO);
}
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
@Override
public boolean create(LoginHistory obj) {
return loginHistoryDAO.create(obj);
}
这部分是DAO层
@Repository("loginHistoryDAO")
公共类LoginHistoryDAOImpl扩展GenericDAOImpl实现LoginHistoryDAO {
@Autowired
private SessionDAO sessionDAO;
@Override
public boolean create(LoginHistory obj) {
try {
//beginTransaction();
save(obj);
if (obj.isAccountVerified()) {
Session s = new Session();
s.setActive(Boolean.TRUE);
s.setIpAddress(obj.getIpAddress());
s.setCreated(new Date());
s.setSessionId(obj.getSessionId());
s.setUser(obj.getUser());
sessionDAO.save(s);
}
//commitTransaction();
} catch (Exception e) {
handleException(e);
return false;
}
return true;
}
}
最后一部分是通用部分
@SuppressWarnings("unchecked")
@Repository 公共抽象类GenericDAOImpl实现GenericDAO {
@Autowired
private SessionFactory sessionFactory;
private final Class<T> persistentClass;
public GenericDAOImpl() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getPersistentClass() {
return persistentClass;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getCurrentSession() throws HibernateException {
return sessionFactory.getCurrentSession();
}
@Override
public Transaction beginTransaction() {
return getCurrentSession().beginTransaction();
}
@Override
public void commitTransaction() {
getCurrentSession().getTransaction().commit();
我正在尝试将openSession()替换为getCurrentSession() 我需要控制beginTransaction()和tx.commit()。因为我有多个实体可以同时保存或更新。所以,我需要在事务中包含这些内容,确保所有内容都完成或者所有内容都没有完成。
当我使用getCurrentSession()时,我收到此错误;
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.virdyn.grid.core.system.filter.SessionFilter.doFilter(SessionFilter.java:88)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
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:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
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:744)
引起:org.springframework.transaction.TransactionSystemException:无法提交Hibernate事务;嵌套异常是org.hibernate.TransactionException:事务未成功启动 在org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:660) 在org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) 在org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:412) 在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) at com.sun.proxy。$ Proxy166.create(Unknown Source) 在com.virdyn.grid.controller.UserController.loginAttempt(UserController.java:75) 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:606) 在org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:421) 在org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:409) 在org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771) 在org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716) 在org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) ......还有25个 引起:org.hibernate.TransactionException:事务未成功启动 在org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:100) 在org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656) ... 43更多
我想取消ThreadLocal并使用getCurrentSession。 这里有什么问题还是你有其他目的。实际上我可以对所有dao中的任何方法使用opensession()和closeSession。如果我这样做是为了减慢我的系统? 我在等待解决方案谢谢