@Transactional 不适用于 spring 和休眠(没有活动事务,get 无效)
@Transactional not working with spring and hibernate (get is not valid without active transaction)
我创建了一个 spring-mvc 应用程序。配置如下所示:
调度员-servlet.xml
<beans >
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<context:component-scan base-package="my.server.controller" />
</beans>
applicationContext.xml
<beans >
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="my.server.dao" />
<context:component-scan base-package="my.server.service" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/jahanserver" />
<property name="username" value="postgres" />
<property name="password" value="postgres" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>my.server.entity.TreeItem</value>
<value>my.server.entity.TreeItemDetail</value>
<value>my.server.entity.LayerItem</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.spatial.dialect.postgis.PostgisDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.default_schema">public</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
applicationContext.xml
由 web.xml
中的以下行加载:
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml, /WEB-INF/security.xml</param-value>
</context-param>
my.server.service.TreeServiceImpl
@Service
public class TreeServiceImpl implements TreeService {
@Inject
TreeDao treeDao;
@Override
@Transactional
public TreeItem getTreeItem(Long id) {
return treeDao.getTreeItem(id);
}
}
my.server.dao.TreeDaoImpl
@Service
@Singleton
public class TreeDaoImpl extends AbstractDaoImpl implements TreeDao{
public TreeItem getTreeItem(Long id){
return (TreeItem)sessionFactory.getCurrentSession().get(TreeItem.class, id);
}
...
}
my.server.controller.TreePermissionController.java
@RestController
@RequestMapping("/treePermission")
public class TreePermissionController implements InitializingBean{
@Inject
TreeService treeService;
private final PermissionFactory permissionFactory = new DefaultPermissionFactory();
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(treeService, "HBUtil cannot be null");
}
@RequestMapping(method = RequestMethod.GET, value = "/addPermission")
public TreeItem addPermission(HttpServletRequest request,
@RequestParam Long id ) throws IOException {
TreeItem item = treeService.getTreeItem(id);
PrincipalSid sid = new PrincipalSid("dariush");
Permission permission = permissionFactory.buildFromMask(16);
try {
treeService.addPermission(item, sid, permission);
} catch (DataAccessException existingPermission) {
existingPermission.printStackTrace();
}
return item;
}
}
在控制器中我称之为:
TreeItem item = treeService.getTreeItem(id);
我遇到了这个错误:
org.hibernate.HibernateException: get is not valid without active transaction
问了一些相同问题的问题。我遵循了所有建议,但这对我来说仍然是个问题。
我该如何解决?请帮忙!
使用 spring 和 spring 托管事务时,切勿使用 hibernate.current_session_context_class 属性,除非您使用的是 JTA。
实际上 Spring 将默认设置其自己的 CurrentSessionContext 实现(SpringSessionContext),但是如果您自己设置它,则情况并非如此,这意味着它破坏了正确的事务集成。
所以请 remove/Comment-Out 下面一行
applicationContext.xml
中的 hibernateProperties
<prop key="hibernate.show_sql">true</prop>
希望这能解决您的错误
我创建了一个 spring-mvc 应用程序。配置如下所示:
调度员-servlet.xml
<beans >
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<context:component-scan base-package="my.server.controller" />
</beans>
applicationContext.xml
<beans >
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="my.server.dao" />
<context:component-scan base-package="my.server.service" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/jahanserver" />
<property name="username" value="postgres" />
<property name="password" value="postgres" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>my.server.entity.TreeItem</value>
<value>my.server.entity.TreeItemDetail</value>
<value>my.server.entity.LayerItem</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.spatial.dialect.postgis.PostgisDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.default_schema">public</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
applicationContext.xml
由 web.xml
中的以下行加载:
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml, /WEB-INF/security.xml</param-value>
</context-param>
my.server.service.TreeServiceImpl
@Service
public class TreeServiceImpl implements TreeService {
@Inject
TreeDao treeDao;
@Override
@Transactional
public TreeItem getTreeItem(Long id) {
return treeDao.getTreeItem(id);
}
}
my.server.dao.TreeDaoImpl
@Service
@Singleton
public class TreeDaoImpl extends AbstractDaoImpl implements TreeDao{
public TreeItem getTreeItem(Long id){
return (TreeItem)sessionFactory.getCurrentSession().get(TreeItem.class, id);
}
...
}
my.server.controller.TreePermissionController.java
@RestController
@RequestMapping("/treePermission")
public class TreePermissionController implements InitializingBean{
@Inject
TreeService treeService;
private final PermissionFactory permissionFactory = new DefaultPermissionFactory();
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(treeService, "HBUtil cannot be null");
}
@RequestMapping(method = RequestMethod.GET, value = "/addPermission")
public TreeItem addPermission(HttpServletRequest request,
@RequestParam Long id ) throws IOException {
TreeItem item = treeService.getTreeItem(id);
PrincipalSid sid = new PrincipalSid("dariush");
Permission permission = permissionFactory.buildFromMask(16);
try {
treeService.addPermission(item, sid, permission);
} catch (DataAccessException existingPermission) {
existingPermission.printStackTrace();
}
return item;
}
}
在控制器中我称之为:
TreeItem item = treeService.getTreeItem(id);
我遇到了这个错误:
org.hibernate.HibernateException: get is not valid without active transaction
问了一些相同问题的问题。我遵循了所有建议,但这对我来说仍然是个问题。 我该如何解决?请帮忙!
使用 spring 和 spring 托管事务时,切勿使用 hibernate.current_session_context_class 属性,除非您使用的是 JTA。
实际上 Spring 将默认设置其自己的 CurrentSessionContext 实现(SpringSessionContext),但是如果您自己设置它,则情况并非如此,这意味着它破坏了正确的事务集成。
所以请 remove/Comment-Out 下面一行 applicationContext.xml
中的 hibernateProperties<prop key="hibernate.show_sql">true</prop>
希望这能解决您的错误