我有一个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在咨询外键模型之前关闭了会话。
如何避免这个问题?
答案 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