springcloud JPA 懒加载失败

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springcloud JPA 懒加载失败相关的知识,希望对你有一定的参考价值。

如题:实体类中配置了
@OneToMany(mappedBy = "productTypeId",cascade=CascadeType.REFRESH,fetch = FetchType.LAZY)
//@NotFound(action= NotFoundAction.IGNORE)//代表可以为空,允许为null
private List<WxProductEntity> productList;

后台打印SQL仍是n+1条
两个实体分别为商品和商品分类。对应的数据库表中没有做主外键关联,且商品实体没有做任何其他级联配置。以上代码是商品分类实体里的配置。

参考技术A 如在User对象中有一个Role对象的属性:
select u from User u left join fetch u.role;
用fetch实现手动加载追问

我要的是懒加载哦。

参考技术B 老铁解决没呢?我用的也是SpringBoot(SpringCloud)+ResultFul+SpringJpa,OneToOne懒加载,一直都不行,把关联表全查出来了~然后数据太多导致服务请求超时== 参考技术C spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

配置文件里加这个

jpa如何懒加载大字段,懒加载之后又如何获取懒加载字段

前言:对于大字段,我们在查询列表的时候不需要查询,但是修改的时候有需要展示大字段内容,怎么办

问1.jpa如何懒加载大字段?即查询列表的时候不查询出来

问2.懒加载之后又如何获取懒加载字段。比如,在后台修改的实体的时候,需要展示内容,如何获取detail内容(懒加载,它没有加载)

1.jpa如何懒加载大字段?detail是我的大字段

@Entity
public class ParkDynamics extends TemporalEntity implements FieldHandled{},实现FieldHandled

具体实体代码如下

@Entity
public class ParkDynamics extends TemporalEntity implements FieldHandled {
    private String title; //标题
    private String content; //内容
    private String status; //状态 (0:不可见;1:可见)
    private String remarks; //备注
    private String creatorName;
    private String updatorName;

    @Lob
    @Basic(fetch = FetchType.LAZY)
    @Column(name="detail")
    private String detail;//图文交替型内容(用文本编辑器)

    @OneToMany(mappedBy = "parkDynamics",fetch = FetchType.EAGER)
    private Set<ParkDynamicsFile> parkDynamicsFiles = new HashSet<>(); //公园动态文件

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getRemarks() {
        return remarks;
    }

    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }

    public String getCreatorName() { return creatorName; }

    public void setCreatorName(String creatorName) { this.creatorName = creatorName; }

    public String getUpdatorName() { return updatorName; }

    public void setUpdatorName(String updatorName) { this.updatorName = updatorName; }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Set<ParkDynamicsFile> getParkDynamicsFiles() { return parkDynamicsFiles; }

    public void setParkDynamicsFiles(Set<ParkDynamicsFile> parkDynamicsFiles) { this.parkDynamicsFiles = parkDynamicsFiles; }

    public String getDetail() {
        if (fieldHandler != null) {
            return (String) fieldHandler.readObject(this, "detail    ", detail);
        }
        return null;
    }

    public void setDetail(String detail) {
        if(detail == null){
            if(fieldHandler!=null){
                fieldHandler.writeObject(this, "detail", this.detail, detail);
                return;
            }
        }
        this.detail = detail;
    }
    @Transient
    private FieldHandler fieldHandler;//用于延迟加载表字段,关联对象延迟加载的话无需此技术

    @JsonIgnore
    public FieldHandler getFieldHandler() {
        return fieldHandler;
    }

    public void setFieldHandler(FieldHandler fieldHandler) {
        this.fieldHandler = fieldHandler;
    }
}

2.对于懒加载的字段,如何获取其内容呢

关键代码如下:(String) fieldHandler.readObject(this, "detail ", detail);,相当于去读对象的detail属性,然后会真是的加载detail的内容。this代表实体对象,这样实体对象就detail就有内容了。

但是实际如果不是在一个事务中是不行的。也就是获得实体使实体去加载懒加载的字段不在同一个事务中,你执行(String) fieldHandler.readObject(this, "detail ", detail)是会报错的。

也就有了如下的代码,对需要获取实体全部内容的getById和getByType进行了封装,放在一个事务service类中

@Transactional
@Service
public class AnimalClassServiceImpl implements AnimalClassService{
    @Autowired
    private AnimalClassRepository animalClassRepository;
	@Override
	public AnimalClass getById(Long id) {
		AnimalClass animalClass = animalClassRepository.getById(id);
		animalClass.setContent(null);
		return animalClass;
	}
	@Override
	public AnimalClass getFirstByType(String type) {
		AnimalClass animalClass = animalClassRepository.getFirstByType(type);
		animalClass.setContent(null);
		return animalClass;
	}

}

  

 


以上是关于springcloud JPA 懒加载失败的主要内容,如果未能解决你的问题,请参考以下文章

JPA懒加载如何手动加载

jpa如何懒加载大字段,懒加载之后又如何获取懒加载字段

jpa 关于懒加载的问题

[JavaEE - JPA] 性能优化: 4种触发懒加载的方式

JPA 懒加载问题

JPA数据懒加载LAZY和实时加载EAGER(转)