fetch = FetchType.LAZY 无法获得 entity 对象
时间: 2023-09-04 19:10:14 浏览: 54
这个问题很明显是关于JPA的,fetch = FetchType.LAZY是一种延迟加载的方式,它表示在默认情况下,当从数据库中获取一个实体对象时,与该实体对象相关联的属性不会立即从数据库中加载,而是在第一次访问它们时才会被加载。因此,如果你在使用该实体对象相关联的属性之前没有访问它们,那么它们就不会被加载到内存中,从而导致无法获取该实体对象。所以,你需要确保在访问与实体对象相关联的属性之前,调用它们的getter方法,以触发它们的加载。
相关问题
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
这是JPA注解中的@OneToMany注解,用于描述实体类之间的一对多关系。其中,mappedBy属性指定了另一个实体类中与当前实体类的关联属性名,表明当前实体类是另一个实体类中的多方。cascade属性指定了级联操作,即当对当前实体类进行操作时,是否对与之关联的另一个实体类进行相应的操作。fetch属性指定了查询时的抓取策略,即如何加载与之关联的另一个实体类。具体解释如下:
1. mappedBy属性
对于一对多的关系,通常会在多的一方使用@OneToMany注解来描述,而在一的一方使用@ManyToOne注解来描述。mappedBy属性用于指定多的一方中与一的一方对应的属性名,以建立关联关系。例如:
```java
@Entity
public class User {
@Id
private Long id;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Order> orders;
// getter and setter
}
@Entity
public class Order {
@Id
private Long id;
@ManyToOne
private User user;
// getter and setter
}
```
在这个例子中,User实体类中使用了@OneToMany注解来描述与Order实体类的一对多关系,其中mappedBy属性指定了Order实体类中与User实体类对应的属性名user。
2. cascade属性
cascade属性用于指定级联操作,即当对当前实体类进行操作时,是否对与之关联的另一个实体类进行相应的操作。常用的级联操作包括:
- CascadeType.PERSIST:级联新增操作,保存当前实体类时,对与之关联的另一个实体类进行新增操作。
- CascadeType.REMOVE:级联删除操作,删除当前实体类时,对与之关联的另一个实体类进行删除操作。
- CascadeType.MERGE:级联更新操作,更新当前实体类时,对与之关联的另一个实体类进行更新操作。
- CascadeType.ALL:包含所有级联操作。
在实际开发中,需要根据业务需求选择合适的级联操作。例如,对于一对多的关系,通常使用CascadeType.ALL,表示对User实体类的任何操作都会级联到Order实体类中。
3. fetch属性
fetch属性用于指定查询时的抓取策略,即如何加载与之关联的另一个实体类。常用的抓取策略包括:
- FetchType.LAZY:延迟加载,只有在访问与之关联的另一个实体类时才会进行加载。
- FetchType.EAGER:立即加载,查询当前实体类时会同时查询与之关联的另一个实体类。
在实际开发中,需要根据查询场景选择合适的抓取策略。对于一对多的关系,通常使用FetchType.LAZY,避免在查询User实体类时同时查询所有关联的Order实体类,提高查询性能。
@Data @AllArgsConstructor @NoArgsConstructor @Builder @Table(name = "advert") public class Advert { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @ApiModelProperty(value = "广告唯一id") private Integer id; @ApiModelProperty(value = "广告名称") @NotBlank(message = "广告名称不可为空", groups = {AddGroup.class, UpdateGroup.class}) private String name; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "position_id") private AdPosition position; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "media_id") private MediaFile media; } @Data @AllArgsConstructor @NoArgsConstructor @Builder @Table(name = "ad_position") public class AdPosition { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @ApiModelProperty(value = "位置名称") @NotBlank(message = "位置名称不可为空", groups = {AddGroup.class}) private String name; @OneToMany(mappedBy = "AdPosition", cascade = CascadeType.ALL) private List<Advert> adverts = new ArrayList<>(); } @Data @AllArgsConstructor @NoArgsConstructor @Builder @Table(name = "media_file") public class MediaFile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @ApiModelProperty(value = "媒体文件名称") private String fileName; @ApiModelProperty(value = "媒体文件类型") private Integer fileType; @ApiModelProperty(value = "媒体文件URL地址") private String fileUrl; @OneToMany(mappedBy = "MediaFile", cascade = CascadeType.ALL) private List<Advert> adverts = new ArrayList<>(); } public interface MyBaseMapper<T> extends Mapper<T>, MySqlMapper<T>,MyInsertListMapper<T> {} public interface AdvertMapper extends MyBaseMapper<Advert> {},如何在查询advert表时,将关联的其余两张表的数据一并查询出来?请将mapper.xml文件全部展示出来
AdvertMapper.xml文件如下:
```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.AdvertMapper">
<resultMap id="advertMap" type="com.example.entity.Advert">
<id property="id" column="id" />
<result property="name" column="name" />
<association property="position" column="position_id" javaType="com.example.entity.AdPosition">
<id property="id" column="id" />
<result property="name" column="name" />
</association>
<association property="media" column="media_id" javaType="com.example.entity.MediaFile">
<id property="id" column="id" />
<result property="fileName" column="file_name" />
<result property="fileType" column="file_type" />
<result property="fileUrl" column="file_url" />
</association>
</resultMap>
<select id="selectAdvert" resultMap="advertMap">
SELECT a.id, a.name, a.position_id, a.media_id, p.name as position_name, m.file_name, m.file_type, m.file_url
FROM advert a
LEFT JOIN ad_position p ON a.position_id = p.id
LEFT JOIN media_file m ON a.media_id = m.id
WHERE a.id = #{id}
</select>
</mapper>
```
在上面的XML文件中,我们定义了一个名为advertMap的结果映射,它将advert表、ad_position表和media_file表的数据全部查询出来。我们还定义了一个名为selectAdvert的查询语句,它使用advertMap作为结果映射,并在SELECT语句中使用LEFT JOIN将三个表连接起来。最后,我们将这个查询语句的ID设置为selectAdvert,以便在Java代码中调用它。