休眠中的延迟加载

时间:2019-05-20 17:05:21

标签: spring hibernate lazy-loading many-to-one

我无法使惰性加载在Spring上工作。

@Entity
public class Livro {

    @JsonInclude(Include.NON_NULL)
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotEmpty(message = "Campo nome é obrigatorio")
    private String nome;

    @JsonInclude(Include.NON_NULL)
    @JsonFormat(pattern = "dd/mm/yyy")
    @NotNull(message = "Campo publicacao é obrigatorio")
    private Date publicacao;

    @JsonInclude(Include.NON_NULL)
    private String editora;

    @JsonInclude(Include.NON_NULL)
    private String resumo;

    @OneToMany( mappedBy = "livro", fetch = FetchType.LAZY )
    private List<Comentario> comentarios;

// Comentario.Java

@Entity
public class Comentario {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @JsonProperty("comentario")
    private String texto;

    private String usuario;

    @JsonFormat(pattern = "dd/mm/yyy")
    private Date data;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "LIVRO_ID")
    @JsonIgnore
    private Livro livro;

// LivrosRepository.java

package com.curso.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.curso.domain.Livro;

public interface LivrosRepository extends JpaRepository<Livro, Long> {

}

// ComentariosRepository.java

package com.curso.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.curso.domain.Comentario;

public interface ComentariosRepository extends JpaRepository<Comentario, Long> {



}

// LivrosService.java

@Service
public class LivrosService {

    @Autowired
    private LivrosRepository livrosRepository;

    @Autowired
    private ComentariosRepository comentariosRepository;

   // [...]

    public List<Livro> listar() {
        return livrosRepository.findAll();
    }
}

当我请求列出书籍时,我期望的行为是我列出了书籍中的所有数据,但没有注释,因为我使用的是Java注释 fetch = FetchType.LAZY,但是我的行为是返回工作簿中的所有数据。

[
    {
        "id": 4,
        "nome": "Teste2",
        "publicacao": "01/01/2018",
        "editora": "Polenta",
        "comentarios": [
            {
                "id": 1,
                "usuario": "tester",
                "data": "26/03/2019",
                "comentario": "Comentario 1"
            }
        ]
    }
]

1 个答案:

答案 0 :(得分:0)

使用@Transactional的方法中存在休眠会话。在Service类之外传递实体是一种不好的做法,因为在离开您的listar方法之后,会话正在关闭。另一方面,您的实体包含延迟初始化的集合(List<Comentario> comentarios),一旦关闭会话,就无法提取它们。

好的做法是将实体映射到传输对象上,然后从服务(不是原始实体)中返回那些传输对象。

首先,您应该用public List<Livro> listar()包装@Transactional方法。在执行此方法期间,Hibernate Session将保持活动状态。这意味着您可以在此方法中提取惰性的初始化元素。 其次,您应该使用所有必填字段定义LivroDto类,并将Livro实体映射到此方法内的POJO上,然后从服务中返回LivroDro