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

获取EAGER获取对象OneToOne时的LazyLaunalizationException

孔飞翔
2023-03-14

我有两个实体

@Entity
@Table(name = "user")
@Data
@Builder
@EqualsAndHashCode(callSuper=false)
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "name")
    private String name;    
    
    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @PrimaryKeyJoinColumn
    private UserLastLogin userLastLogin;
}


@Entity
@Table(name = "lastLogin")
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@ToString(onlyExplicitlyIncluded = true)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserLastLogin implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "name")
    private String userName;

    @Column(name = "date")
    private LocalDateTime date;

    @OneToOne
    @MapsId
    @JoinColumn(name = "name")
    private User user;

}

我使用带有spring数据的spring boot和最新版本的jpa、hibernate。在文档中,@OneToOne是默认的EAGER,但当我获取EAGER fetch对象时,当我在get方法中不使用@Transactional时,我会得到lazyInitializationException。我不明白为什么。。。

    public UserDto getUser(String userName) {
        var user= userRepository.getById(userName);     
        d.getSystemUserLastLogin(); // this throw lazy initialization exception
        return mapper.entityToDto(d);
    }

当我将这个方法标记为@Transactional时,这个工作。但是,不建议在get方法中使用最终事务。我需要在这段关系中使用渴望的获取。

当我查看查询Hibernate时,我有一个选择,但子对象不可用。

Hibernate: 
    select
        user0_.name as nazwa1_4_0_,        
        user2_.name as name1_23_2_,        
        user2_.data as data3_23_2_ 
    from
        user0_     
    left outer join
       last_login user2_ 
            on user0_.name=user2_.name 
    where
        user0_.name=?

共有2个答案

鲜于允晨
2023-03-14

我建议您使用如下二级表:

@Entity
@Table(name = "user")
@Data
@Builder
@EqualsAndHashCode(callSuper=false)
@ToString
@AllArgsConstructor
@NoArgsConstructor
@SecondaryTable(name = "lastLogin", pkJoinColumns = @PrimaryKeyJoinColumn(name = "name"))
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "name")
    private String name;    
    
    @Column(table = "lastLogin", name = "date")
    private LocalDateTime date;
}

有关更多详细信息,请参阅https://www.baeldung.com/jpa-mapping-single-entity-to-multiple-tables。

秦涵涤
2023-03-14

问题是尽管fetch渴望,但还是使用了懒。这是由于使用了存储库中的getById方法,该方法仅检索对象的引用并在检索懒时抓取所有字段。更改为findById解决了问题,因为findById接受的是对象,而不是引用。

 类似资料:
  • 我有以下实体: 我尝试过创建@OneToOne(FetchType.lazy),但不起作用,它仍然提取不需要的信息。 如何避免获取复合对象? 我希望最终结果不包含Address对象,因为它在20个场景中需要一次,我可以分别获取它们。 任何想法,如何实现这一点。 谢谢

  • 一般来说,我们可以通过 query() 方法来查询物体(即获取对象)。找到物体后,就可以通过 ThingJS API 提供的功能来控制该物体了。本节教程中,主要介绍 query() 查询的方法。 另外,我们还可以通过父子属性或者分类属性来查询物体,参阅参考信息中的其他查询方法。 获取对象的语法 通常,我们可以通过 query() 方法来获取对象/物体。 var obj = app.query(va

  • 前面说了Ioc初始化的log,这里说的是Ioc.get产生的log, 也就是从Ioc容器获取bean的log 2015-03-30 10:49:49,729 org.nutz.mvc.impl.NutLoading.evalSetup(NutLoading.java:253) INFO - Setup application... 2015-03-30 10:49:49,729 org.nutz

  • 问题内容: 这个问题很简单,但是由于我是python的新手,所以我从php过来了,因此遇到了一些错误。 我有以下简单的课程: 在PHP中,我可以执行以下操作: 我该如何在python中做到这一点? 问题答案: 要访问对象的字段或方法,请使用dot : 如果将在运行时定义字段名称,请使用内置函数:

  • 当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢? 使用type() 首先,我们来判断对象类型,使用type()函数: 基本类型都可以用type()判断: >>> type(123) <type 'int'> >>> type('str') <type 'str'> >>> type(None) <type 'NoneType'> 如果一个变量指向函数或者类,也可以用type

  • 当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢? 使用type() 首先,我们来判断对象类型,使用type()函数: 基本类型都可以用type()判断: >>> type(123) <class 'int'> >>> type('str') <class 'str'> >>> type(None) <type(None) 'NoneType'> 如果一个变量指向函数或者类,