@RunWith(SpringJunit4ClassRunner.class)
@WebAppConfiguration
@ContextHierarchy({
@ContextConfiguration(name = "root", locations = "classpath:application.xml"),
@ContextConfiguration(name = "servlet", locations = "classpath:servlet.xml")
})
@TransactionalConfiguration
public class IntegrationTest {
private MockMvc mockMvc;
//some initialization and autowiring
@Test
@Transactional // It is important to rollback all the db changes after the test. So, it's a common pattern to make all tests transactional.
// So here we have HibernateSession#1
public void testController() {
// repository is spring-data-jpa repository
// but you may think of it as a DAO which returns persisted
// hibernate entity
ChildEntity child = new ChildEntity();
child = childRepository.save();
MyEntity entity = new MyEntity();
entity.setChildEntities(Collections.singletoneList(child));
entity = repository.save(entity);
// entity and its child are still preserved in the HibernateSession#1
mockMvc.perform(get("/entity/by_child_id/" + child.getId()).andExpect(status().is("200"));
}
}
@RestController
@RequestMapping("/entity")
public class MyController {
@RequestMapping("by_child_id/{id}")
// My guess: Jackson hibernate mapper will open another session
// and try to fetch children
// So here we have HibernateSession#2
public MyEntity getByChildId(@PathVariable("id") childId) {
return repository.findByChildrenId(childId);
}
}
@Entity
public class MyEntity {
@OneToMany(fetch = FetchType.EAGER)
private List<ChildEntity> children;
}
//and finally here is a piece of servlet.xml
<mvc:annotation-driven>
<mvc:message-converters>
<!-- Use the HibernateAware mapper instead of the default -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="path.to.your.HibernateAwareObjectMapper" />
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Caused by org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions: [MyEntity.children#1]
at com.fasterxml.jackson.datatype.hibernate4.PersistentCollectionSerializer.inistializeCollection(PersistentCollectionSerializer.java:195)
at com.fasterxml.jackson.datatype.hibernate4.PersistentCollectionSerializer.findLazyValue(PersistentCollectionSerializer.java:160)
at com.fasterxml.jackson.datatype.hibernate4.PersistentCollectionSerializer.serialize(PersistentCollectionSerializer.java:115)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase:639)
jackson-databind-2.4.2.jar
那么,除了避免使用jackson-hibernate-mapper进行测试之外,还有什么方法可以避免这个问题吗?使用DTO和Dozer代替domain object不被认为是一种解决方案(将来会这样做,但不是现在)。
提前致谢
多亏了M.Deinum,我决定使用最简单的解决方案,并创建了一个test-servlet-context.xml:
<beans>
<import resource="classpath:servlet.xml">
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</beans>
此外,我还更改了servlet.xml中转换器的定义:
<mvc:annotation-driven>
<mvc:message-converters>
<!-- Use the HibernateAware mapper instead of the default -->
<ref bean="jsonConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="path.to.your.HibernateAwareObjectMapper" />
</property>
</bean>
现在我的测试没有使用任何jackson-hibernate魔法。这是没有用的,因为所有的测试本身都是事务性的。
我试图更新MySql数据库中的记录。更新时引发了以下异常 我检查会话。它关闭在每个方法的最后块中。无法弄清楚出了什么问题。我能够毫无问题地使用其他方法插入更新操作,但只有保存更新用户豆方法抛出异常 UserDAOImpl: 服务输入: applicationContext.xml: 我能够使用相同的配置执行所有数据库操作,但当我从serviceImpl调用块用户()方法时,它调用DAO方法,并且S
我使用Hibernate和Spring,我在执行以下代码时得到这个异常: 我已经阅读了一些关于Hibernate的会话管理,我有一种预感,这段代码的会话处理很差。举行两次公开会议的原因可能是什么?Hibernate API表示函数返回一个新的会话对象或现有的会话对象。在这种情况下,它从哪里获取现有会话对象?如果它创建了一个新的会话对象,那么处理所涉及的集合仍然可以吗? 任何帮助将不胜感激。提前感谢
我在我的单元测试中看到了上面的错误,并且不知道如何纠正它。 我的单元测试类扩展了abstracttransactiondatasourcespringcontexttests并执行以下操作: 下面是我的规则组映射文件的一个片段。如您所见,RuleGroup封装了规则和属性集合,默认情况下这两者都是延迟加载的: 我的DAO类扩展了HibernateDaoSupport: 通过调试我的测试,在find
在我当前的 spring 项目中,当我的应用程序尝试执行此方法时: 我得到了这个错误: 我的Dao类(插入方法的位置)是这样的: 我还尝试在Dao类中的insert、update和delete方法以及在服务类中使用它们的方法中添加注释@Transaction,但同样的问题也会发生。 有人能看出我做错了什么吗? ps.:我试图保存的实体类是:
我在Hibernate4中使用JTA事务管理器。有人知道这个问题吗?在执行刷新时,我面临错误。 下面是我面临上述问题的一段代码。 XML:
问题内容: 首先,我将Java EE与EntityManager和PrimeFaces一起使用Hibernate。 我有一个EJB模块(业务逻辑和域)和两个WAR模块(Jersey WS和JSF PrimeFaces)。 我决定在JSF WAR模块中初始化延迟集合,以避免延迟初始化异常。我不使用扩展实体管理器。 我得到: 我不明白 从数据库中获取初始化之前的一行时,必须有一个会话,不是吗?我以类似