(springboot +休眠+ jparepository)错误-没有会话,正在绑定GET

时间:2018-12-19 15:34:54

标签: hibernate spring-boot spring-data-jpa

我有一个SpringBoot项目,其中我实体的一个属性是LAZY,但是当我尝试获取依赖于该实体的表时(我只是想使用Postman),我会不断收到此错误- >

{
    "timestamp": 1545232817105,
    "status": 500,
    "error": "Internal Server Error",
    "message": "Could not write JSON: failed to lazily initialize a collection of role: br.com.quantus.fonumS3_api.model.GesUsuarios.fnmCampanhaOpesForFnmCampanhaOpeOperador, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: br.com.quantus.fonumS3_api.model.GesUsuarios.fnmCampanhaOpesForFnmCampanhaOpeOperador, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->br.com.quantus.fonumS3_api.model.GesUsuarios[\"fnmCampanhaOpesForFnmCampanhaOpeOperador\"])",
    "path": "/FonumAPI/GesUsuarios"
}

这是我设置模型,存储库和资源的方式:

//MODEL
@Entity
@Table(name = "ges_usuarios_015", schema = "public", uniqueConstraints = @UniqueConstraint(columnNames = "login_015"))
public class GesUsuarios implements java.io.Serializable {

    private static final long serialVersionUID = 6598890791981509364L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "codigo_015", unique = true, nullable = false)
    private Integer codigo015;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "turno_015")
    private GerTurno gerTurno;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "tipo_015")
    private GerTipoUsuario gerTipoUsuario;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "status_015")
    private GerStatusUsuario gerStatusUsuario;
    ....


//REPOSITORY
import org.springframework.data.jpa.repository.JpaRepository;
import model.GesUsuarios;

public interface GesUsuariosRepository extends JpaRepository<GesUsuarios, Integer> {

}

//RESOURCE
@CrossOrigin("${origem-permitida}")
@RestController
public class GesUsuariosResource {

    @Autowired
    private GesUsuariosRepository gesUsuariosRepository;    

    @GetMapping("/GesUsuarios")
    public List<GesUsuarios> ListarGesUsuarios(){   
    return gesUsuariosRepository.findAll();
    }
    ....

我不能使用EAGER,因为我的数据库中有大量数据,因此它变得很慢。另一方面,当使用LAZY时,我一直遇到这个问题。
我相信是因为jpa在咨询外键模型之前关闭了会话。

如何避免这个问题?

1 个答案:

答案 0 :(得分:0)

在上述解决方案中,您正在检索模型并将其作为响应的一部分直接发送出去。在此过程中,您的响应会尝试访问这些字段,以将其转换为可发送格式(xml / json / text)。

如果要使这些字段简单为空,则应在此处创建一个表示形式的模型,在该模型中,您将实体字段映射到表示形式,然后跳过延迟加载的字段(如果/当您创建新查询映射到制图表达时尝试访问这些字段。

spring boot表示只是一个POJO,没有附加的JPA注释(就像您的实体一样),它将自动转换为您的端点生成的类型。

在您的代码中,特别是创建此代码后,它看起来将像这样:

@GetMapping("/GesUsuarios")
    public List<GesUsuarios> ListarGesUsuarios(){
    List<GesUsuarios> usuariosModels = gesUsuariosRepository.findAll();
    List<UsuariosRepresentation> usuarios;

    for(GesUsuarios usuariosModel : usuarios) {
      UsuariosRepresentation usuario = new UsuariosRepresentation();

      usuario.setField1(usuariosModel.getField1());
      ... //Do not include the lazily loaded pieces here, unless  you specifically want them.

      usuarios.add(usuario);
    }

    return usuarios;
}

最后,我还要看看从您的存储库中返回Optionals的情况,在这里它们很有用。

可选阅读: Baeldung - Optionals