gpt4 book ai didi

spring - 尽管在 @Transactional 中并且没有分离的实体,但仍获取 LazyInitializationException

转载 作者:行者123 更新时间:2023-12-04 18:03:22 25 4
gpt4 key购买 nike

我使用的是 Spring 3.2.11.RELEASE、JPA 2.1、Hibernate 4.3.6.Final 和 MySQL 5.5.37。我在 JUnit 测试中遇到以下错误

testSendValidAssignment(org.mainco.subco.thirdParty.service.ThirdPartyServiceIT)  Time elapsed: 13.366 sec  <<< ERROR!
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.mainco.subco.lessonplan.domain.LessonPlan.classrooms, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:278)
at org.mainco.subco.ThirdParty.service.ThirdPartyServiceIT.testSendValidAssignment(ThirdPartyServiceIT.java:102)

但是,我不知道这条错误消息应该归咎于哪一行。在我的方法中我有

@Service
@Transactional
public class MyServiceImpl implements MyService
{
....

@Override
public void sendAssignment(final String assignmentId)
{
final Assignment assignment = m_lessonPlanDao.getAssignment(assignmentId);
if (processData(assignment))
{
// Gather the students who have been assigned this assignment
final List<Classroom> classes = lessonPlan.getClassrooms();
System.out.println("got " + classes.size() + " classes.");
// Send one request for each class assignment
for (final Classroom classroom : classes)
{
final List<User> classStudents = m_classroomSvc.findClassStudents(classroom.getId());
System.out.println("got " + classStudents.size() + " students.");

并且两个 System.out 行都打印数字。方法中没有对这个延迟加载集合的其他引用,所以我不知道还有什么要检查我的数据。任何建议表示赞赏。

最佳答案

您的服务方法是事务性的,但您的整个测试方法不是。元素的大小检查是在 JUnit 测试的断言语句中执行的,并且是在服务的事务范围之外完成的,因此会导致延迟初始化异常。您可以选择三种方式

  • 您可以尝试在您的 dao 方法中调用 size() 方法来制作size() 方法的外部调用是安全的。
  • 你可以强制使用你的方法的用户打开事务(记录哪些对象被分离并使其成为契约(Contract)/或使用臭名昭著的 open session in view 模式)
  • 您可以创建一个 DTO 层并将大小作为 DTO 的一部分返回

这三种解决方案各有利弊:

第一个解决方案对于代码的支持者来说会很奇怪,因为他们会发现您调用 getter 没有明显的原因 - 它需要注释。

第二个让界面用户的生活更加艰难

第三种违反DRY原则

附注当然你也可以禁用惰性初始化

关于spring - 尽管在 @Transactional 中并且没有分离的实体,但仍获取 LazyInitializationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31392415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com