【问题标题】:How to manage Lazy Loading in Mapstruct?如何管理 Mapstruct 中的延迟加载?
【发布时间】:2016-07-01 03:22:41
【问题描述】:

我正在处理与数据库中延迟加载的对象相关的问题。

假设我们有以下实体。

@Entity(name = "User")
@Table(name = "USERS")
public class User{
    @Id
    @GeneratedValue
    private int id

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="NOTES_ID")
    private List<Note> notes;
}

Dto 是

@Mapper
public interface UserDtoMapper{

    /** the INSTACE HERE **/

    User fromDto(UserDto dto);

    UserDto toDto(User user);

}

那么,哪一种方法可能是获取所有用户而不会出现 EJBException 的最佳方法,因为我正在获取他们的懒惰?

编辑:解决方案

假设您有以下数据模型

public class User{

    private String name;

    //... other fields

    @OneToMany
    private Set<Address> addresses;
}
  1. 无地址查询,异常:当从 Model 映射到 DTO 时,它会尝试映射 addresses,但由于延迟加载(通过休眠或任何其他框架)最终会出现异常。

此外,您可以忽略 addresses 被映射,如 @Mehmet Bektaş 。但不需要定义source,它是可选的。

@Mapping(target = "addresses", ignore = true)
  1. 获取关系:就是这样。添加join 以查询addresses,剩下的工作由 Mapstruct 完成。

【问题讨论】:

  • 在同一个事务中获取所有必要的数据。这样就不会有延迟加载相关的异常。
  • 您在哪里(在哪个应用层)进行映射?理想情况下,它应该作为事务的一部分发生,或者您指定一个实体图,以确保所有要映射的关系都被急切地加载。

标签: hibernate lazy-loading java-ee-7 mapstruct


【解决方案1】:

您可以使用忽略选项。

 @Mapping(source = "user.id", target = "userId", ignore = true)

但是这样你就无法映射像 eager fetch 类型这样的关系字段。

【讨论】:

    【解决方案2】:

    您可以使用 Mapstruct 在映射时延迟加载您想要的所有实体(假设会话仍处于活动状态)。您不想要的已卸载代理可以通过使用忽略注释来忽略。更多细节在这里。 Can MapStruct do a deep deproxy of Hibernate Entity Classes

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多