【问题标题】:Spring with hibernate dont flush the session after exception errorSpring with hibernate 在异常错误后不刷新会话
【发布时间】:2013-11-19 10:51:58
【问题描述】:

我在 Hibernate 中使用 Spring 事务管理。我的服务层方法是事务性的。当用户尝试创建具有现有 ID 的公司时,在测试用例时会发生此错误。这是我的控制器:

@RequestMapping(value = "/CreateCompany", method = RequestMethod.POST)
public @ResponseBody
String createUser(HttpServletRequest request) {
    String response = null;
    try {

        response = getUserServiceTransaction().save(request);

    } catch (Exception e) {
        if (logger.isErrorEnabled()) {
            logger.error(
                    "ERROR: service URL /CreateCompany; " +
                    "method createUser(..)"+ 
                    e.getMessage());
        }
    }
    return response;
}

服务保存方式:

@覆盖 公共字符串保存(HttpServletRequest 请求)抛出 ServiceException {

    String requestJson = null;
    try {
        requestJson = getUtils().fetchJsonRequestString(request);
        Company company = (Company) getUtils().fromJson(requestJson,
                Company.class);

        String companyId = company.getCompanyId();
        getCompanyDao().save(company);

        List<String> linkedCompanies = null;

        String parentCompanyId = company.getCompanyId();

        linkedCompanies = company.getLinkedCompanies();

        Iterator<String> iterator = linkedCompanies.iterator();

        while (iterator.hasNext()) {
            CompanyLinkage companyLinkage = new CompanyLinkage();
            companyLinkage.setParentCompanyId(parentCompanyId);
            companyLinkage.setChildCompanyId(iterator.next());
            getCompanyLinkageDao().save(companyLinkage);
        }

        requestJson = getUtils().toKendoResponse(true);
    }
    catch (Exception e) {
        logger.error("Error:" + e);
        requestJson = getUtils().toKendoResponse(false);
    }
    return requestJson;

}

我的 DAO:

公共类 CompanyDaoImpl 扩展 HibernateDaoSupport 实现 CompanyDao{

@Override
public void save(Company company) throws DAOException {
    try{
        getHibernateTemplate().save(company);
        getHibernateTemplate().flush();
    }
    catch(Exception e){
        throw new DAOException(e);
    }

}

事务性 bean:

<!-- User Service  -->
<bean id="userService" class="com.ig.avs.adapters.db.service.UserService">
    <property name="companyDao" ref="companyDao"/>
    <property name="companyLinkageDao" ref="companyLinkageDao"/>
    <property name="utils" ref="utils" />
</bean>

<bean id="userServiceTransaction"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="txManager" />
<property name="target" ref="userService" />
<property name="transactionAttributes">

<props>
<prop key="save*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
<prop key="update*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
<prop key="delete*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
<prop key="get*">PROPAGATION_SUPPORTS,readOnly , -java.lang.Exception</prop>
<prop key="find*">PROPAGATION_SUPPORTS,readOnly ,-java.lang.Exception</prop>
<prop key="list*">PROPAGATION_SUPPORTS, readOnly ,-java.lang.Exception</prop>
</props>

在我的 JSP 中,我正在检查我的响应是否为 d:false(我在 getUtils().toKendoResponse(false) 中创建),然后我会向用户显示警告“注册中存在一些问题”

但是一旦在服务层的保存过程中出现错误(重复键错误),代码就会到达服务的末尾。之后控制器中出现另一个错误:

错误 CompanyController:47 - 错误:服务 URL /CreateCompany; com.ig.avs.common.entity.db.Company 条目中的方法 createUser(..)null id(发生异常后不要刷新 Session)

并且控制器将“响应”返回为空。

我已尝试删除我在 dao 层中执行的刷新,但没有帮助。我已经在网站上查看了有关此问题的其他答案,但其中大多数人在出错后没有返回。我发现我的异常并从我的服务中返回,所以不确定另一个刷新发生在哪里。

任何意见都会有很大帮助!

【问题讨论】:

    标签: spring hibernate flush


    【解决方案1】:

    您正在使用 Spring 进行事务管理(以一种非常古老的方式),在您的服务方法结束后,事务被提交并且会话被刷新。因此,与其在服务中捕获异常,不如在控制器中捕获它。

    其他几件事

    1. 不要使用HibernateDaoSupportHibernateTemplate,这些在hibernate 3.0.1(2006 年左右)应该被视为已弃用,只需直接使用SessionFactory
    2. 不要使用TransactionProxyFactoryBean,只需使用@Transactional 注释您的服务并使用&lt;tx:annotation-driven /&gt; 这将为您省去很多麻烦
    3. 您为什么不使用 Spring 映射到 JSON 或从 JSON 映射,而是在服务层中自己做,现在直接绑定到您的 Web 层
    4. 从您的服务方法和 dao 调用来看,您的实体映射也存在问题。为什么要手动设置链接,hibernate 可以解决这个问题,您只需要存储Company

    【讨论】:

    • 谢谢!我从服务中抛出错误并在控制器中捕获它,我终于有了我需要的东西。遗憾的是,我对 J2EE 世界还很陌生,所以我似乎遇到了一些问题。我会尝试你的其他建议。再次感谢..
    猜你喜欢
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 2011-07-15
    • 2013-10-08
    • 1970-01-01
    • 2019-12-07
    相关资源
    最近更新 更多