У меня есть этот проект 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 закрывает сеанс, прежде чем обратиться к модели внешнего ключа.
Как я могу избежать этой проблемы?





В приведенном выше решении вы извлекаете модель и отправляете ее напрямую как часть ответа. Во время этого процесса ваш ответ пытается получить доступ к этим полям, чтобы преобразовать его в формат с возможностью отправки (xml / json / text).
Что нужно сделать здесь, если вы хотите, чтобы эти поля были просто нулевыми, - это создать репрезентативную модель, в которой вы сопоставляете поля сущности с представлением и просто пропускаете лениво загруженные поля (новый запрос будет создан, если / когда вы попытаетесь получить доступ эти поля при отображении в представление).
Представление загрузки Spring - это просто 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 - Опции
Дело в том, что я не могу его игнорировать, мне нужно значение внешнего ключа на моем get
Поэтому, если вам нужен внешний ключ, вам нужно будет создать запрос, который объединяет эти поля, но извлекает только ключ дополнительных таблиц @Query ("выберите u из GesUsuarios u join fetch u.gerTurno join fetch u.gerTipoUsuario join fetch u.gerStatusUsuario ") Затем, как только вы вызовете это и заполните свои представления, вы сможете получить только внешние ключи из этих объединенных таблиц. В приведенном выше примере это будет в вашем репозитории как: @Query ("..") и будет findAll (); прямо под
Добавляя второй комментарий для этого, я вообще не обсуждал его здесь, но вы можете предпочесть для этого нативный запрос. @Query (value = "query ..." nativeQuery = true) List <Object [] >> findAll, где список будет строками, а массив объектов будет столбцами. Затем вы можете сопоставить с представлением, не беспокоясь о jql / hql
Я рекомендую прочитать следующую статью, чтобы решить ваш проблема