当前位置: 首页 > 知识库问答 >
问题:

事务不工作在多对多

申黎明
2023-03-14

我在SpringMVC中的交易有问题。我在ManyToMany中有2个实体(用户,角色)。我有服务,我想获取用户的角色:

public Set<Role> getUserRoles(long id) {
    Set<Role> roles = userRepository.findById(id).getRoles();
    return roles;
}

我的用户类:

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "USER_ROLE", joinColumns = {
        @JoinColumn(name = "ID_USER", referencedColumnName = "ID_USER") }, inverseJoinColumns = {
                @JoinColumn(name = "ID_ROLE", referencedColumnName = "ID_ROLE") })
public Set<Role> getRoles() {
    return roles;
}

当我在控制器中使用它时:

Set<Role> roles=userService.getUserRoles(1);
    for (Role r : roles) {
        System.out.println(r.getName());
    }

我有一个懒惰初始化异常。服务标记为@Transactional和方法

TransactionSynchronizationManager.isActualTransactionActive()

in service方法返回true。

public Set<Role> getUserRoles(long id) {
    Set<Role> roles = userRepository.findById(id).getRoles();
    for (Role r : roles) {
        System.out.println(r.getName());
    }
    return roles;
}

我注意到,当我在服务中打印角色时,我的控制器可以工作。感谢您的任何帮助

编辑

在控制器中,我有代码:

for (Role r : roles) {
        System.out.println(r.getName());
    }

当我的服务方式是:

public Set<Role> getUserRoles(long id) {
    Set<Role> roles = userRepository.findById(id).getRoles();
    return roles;
}

然后System.out.println(userService.getUserRoles(1));在控制器中抛出LazyLaunalizationException,但当我的服务html" target="_blank">方法是:

public Set<Role> getUserRoles(long id) {
    Set<Role> roles = userRepository.findById(id).getRoles();
    for (Role r : roles) {
        System.out.println(r.getName());
    }
    return roles;
}

然后是System.out.println(userService.getUserRoles(1));在控制器工作时

共有2个答案

甘英光
2023-03-14

@Transactional可能仅围绕您的userService。这意味着,当您退出该方法时,事务将被提交。

稍后,在控制器上,您将尝试检索实体的惰性属性(用户角色)。由于您不再在事务中,因此您将获得LazyInitializationException

如果要检索角色,请将控制器标记为@Transactional,或急切地检索角色

逑景铄
2023-03-14

正如您所观察到的,@cinek181992,当 System.out.println 在服务中完成时,它的工作原理是,这是因为您处于事务中,因此可以检索和打印不急切的角色实体关系。请注意,当它尝试读取属性时,它会加载属性的数据,以便下次可以在控制器中读取它。
这是因为它在控制器中失败,因为当服务返回时,事务已结束,并且所获取数据的 System.out.println 会尝试读取事务中尚未加载的实体属性。

你的问题有一些解决方案
如果必须读取@ManyToOne关系(通常是),请将其标记为“渴望”。

有时,我更喜欢,最好不要与服务层之外的实体一起工作,而只将DTO发送到Web层。

 类似资料:
  • 嗨,我正在尝试开发带有事务的spring和hibernate应用程序,我正在使用Spring4。x和hibernate 4。下面是我的代码片段 应用程序上下文。xml servlet上下文。xml 坚持。xml finnaly meservice看起来像这样 和 这里会发生运行时异常,但db记录没有回滚。

  • 我是一个新的Spring和学习的事务概念。无法使@Transactional工作。 用例: 当getEmployee()抛出RuntimeException时,员工和员工详细信息的数据插入应该回滚。但回滚没有发生。我使用的是Oracle数据库11g和spring 4.3.1版本。下面是正在运行的独立java代码。

  • 我正在尝试在数据库中保存对象。正在执行代码并创建实体的Id,但实体未持久化到数据库(未插入行): 从三行(beginTransation,flush,commit)中删除注释解决了问题,但是为什么注释在这里不起作用呢? spring XML: POM xml文件:

  • 请参阅代码。 > 当我调用方法@Async loadMarkUpPCT()时,数据没有提交到表中。它表现得好像是非牵引的。 当我从loadMarkUpPCT(类1)中删除@Async(即非异步)时,数据被提交并按预期正常:事务性) 我希望@Async和@Transactional的结果是一样的,但事实并非如此。请解释一下,我做错了什么? 编辑:我刚编辑过代码日志 流程方面:AppDataLoade

  • 我使用的是grails 1.3.7,代码如下: Grails服务: 我的例外: } 当代码抛出MyException时,我发现以下错误:事务回滚,因为它已被标记为仅回滚 注:如果我更改static transactional=true,则不会发生错误。 知道吗?

  • 我将Spring 3.2.4与JavaFX结合使用,并希望实现一种方法,其中操作将在事务中执行。我在控制器中的代码如下所示: 以及我的应用程序上下文: 尝试运行时,我收到以下错误消息: 该方法存在。删除注释,或者将方法从public更改为private,或者从配置中删除bean,程序就会运行,但事务注释根本不起作用。删除代理目标会导致另一个错误。