0

我正在为一个 webapp 编写测试用例,它需要我模拟控制器并验证 URL 命中的结果。但是,我收到错误“分离的实体传递给持久”。然而,webapp 是实时的并且可以正常工作,这意味着问题出在我的测试上。

我使用以下测试上下文进行休眠

    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                     <prop key="org.hibernate.envers.audit_table_prefix">history_</prop>
                     <prop key="org.hibernate.envers.audit_table_suffix"></prop>
                     <prop key="org.hibernate.envers.revision_type_field_name">_REV_TYPE</prop>
                     <prop key="org.hibernate.envers.revision_on_collection_change">false</prop>
            <prop key="hibernate.enable_lazy_load_no_trans">true</prop>
        </props>
    </property>

上下文不适用于数据库中的表,它在使用持久更新对象时给出上述错误。表模式简化如下

'id' int(11) NOT NULL AUTO_INCREMENT,
'code' varchar(64) NOT NULL,
'num_added' int(11) NOT NULL DEFAULT '0',
'created' datetime NOT NULL,
'updates' datetime NOT NULL,
PRIMARY KEY('id'),
UNIQUE KEY 'uq_code' ('code')

我在stackoverflow上尝试了其他答案,建议id不能存在于被持久化的对象中,因为它导致hibernate相信对象与数据库同步,但是将id留空仍然会产生同样的错误。使用 merge 而不是 persist 会产生一个错误,上面写着

“键‘uq_code’的重复条目‘M923’;SQL [n/a];约束 [null]”

我尝试在每次 URL 命中后刷新会话,就像这样

private void refresh(){
    if(openSessionInViewFilter!=null){
       openSessionInViewFilter.destroy();
       openSessionInViewFilter = new OpenSessionInViewFilter();
       openSessionInViewFilter.setServletContext(servletContext);
       openSessionInViewFilter.setSessionFactoryBeanName("sessionFactory");

       this.controller = MockMvcBuilders.standaloneSetup(Controller).addFilters(openSessionInViewFilter).build();
    }
}

但错误保持不变。同样,将会话参数 singleSession 和 hibernate.transaction.auto_close_session 设置为 true/false 也无济于事。这里有什么问题。

4

1 回答 1

0

错误消息说该字段Code在数据库中必须是唯一的,但您的测试用例正在尝试保留重复项。您的测试用例正在重复使用相同的值,或者它正在尝试使用数据库中已经存在的值。

Duplicate entry 'M923' for key 'uq_code' 

'code' varchar(64) NOT NULL,
于 2016-03-09T14:57:28.310 回答