我正在为一个 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 也无济于事。这里有什么问题。