Estou trabalhando em SpringMVC
, Hibernate
& JSON
mas estou recebendo este erro.
HTTP Status 500 - Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.SerializationFeature.FAIL_ON_EMPTY_BEANS) )
Por favor, verifique minha entidade abaixo
@Entity
@Table(name="USERS")
public class User {
@Id
@GeneratedValue
@Column(name="USER_ID")
private Integer userId;
@Column(name="USER_FIRST_NAME")
private String firstName;
@Column(name="USER_LAST_NAME")
private String lastName;
@Column(name="USER_MIDDLE_NAME")
private String middleName;
@Column(name="USER_EMAIL_ID")
private String emailId;
@Column(name="USER_PHONE_NO")
private Integer phoneNo;
@Column(name="USER_PASSWORD")
private String password;
@Column(name="USER_CONF_PASSWORD")
private String confPassword;
@Transient
private String token;
@Column(name="USER_CREATED_ON")
private Date createdOn;
@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@Fetch(value = FetchMode.SUBSELECT)
@JoinTable(name = "USER_ROLES", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "ROLE_ID") })
private List<ActifioRoles> userRole = new ArrayList<ActifioRoles>();
@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL,mappedBy="userDetails")
@Fetch(value = FetchMode.SUBSELECT)
private List<com.actifio.domain.Address> userAddress = new ArrayList<com.actifio.domain.Address>();
@OneToOne(cascade=CascadeType.ALL)
private Tenant tenantDetails;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConfPassword() {
return confPassword;
}
public void setConfPassword(String confPassword) {
this.confPassword = confPassword;
}
public Date getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
public List<ActifioRoles> getUserRole() {
return userRole;
}
public void setUserRole(List<ActifioRoles> userRole) {
this.userRole = userRole;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public Integer getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(Integer phoneNo) {
this.phoneNo = phoneNo;
}
public List<com.actifio.domain.Address> getUserAddress() {
return userAddress;
}
public void setUserAddress(List<com.actifio.domain.Address> userAddress) {
this.userAddress = userAddress;
}
public Tenant getTenantDetails() {
return tenantDetails;
}
public void setTenantDetails(Tenant tenantDetails) {
this.tenantDetails = tenantDetails;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
Como posso resolver isso?
Respostas:
Tive um problema semelhante com o carregamento lento por meio do objeto proxy de hibernação. Contorne isso anotando a classe com propriedades privadas carregadas lentamente com:
Presumo que você pode adicionar as propriedades em seu objeto de proxy que interrompe a serialização JSON para essa anotação.
O problema é que as entidades são carregadas lentamente e a serialização ocorre antes de serem carregadas totalmente.
fonte
Só para acrescentar, encontrei o mesmo problema, mas as respostas fornecidas não funcionaram. Eu consertei pegando a sugestão da exceção e adicionando ao arquivo application.properties ...
Estou usando Spring Boot v1.3 com Hibernate 4.3
Ele agora serializa o objeto inteiro e os objetos aninhados.
EDIT: 2018
Como isso ainda recebe comentários vou esclarecer aqui. Isso absolutamente apenas esconde o erro. As implicações de desempenho estão aí. Na época, eu precisava de algo para entregar e trabalhar nisso mais tarde (o que fiz através de não usar mais a mola). Então, sim, ouça outra pessoa se você realmente quiser resolver o problema. Se você apenas quer que isso acabe, vá em frente e use esta resposta. É uma ideia terrível, mas, diabos, pode funcionar para você. Só para constar, nunca mais tive um acidente ou problema depois disso. Mas é provavelmente a origem do que acabou sendo um pesadelo de desempenho do SQL.
fonte
"handler":{},"hibernateLazyInitializer":{}
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
Como sugerido corretamente nas respostas anteriores, o carregamento lento significa que, quando você busca seu objeto do banco de dados, os objetos aninhados não são buscados (e podem ser buscados posteriormente, quando necessário).
Agora Jackson tenta serializar o objeto aninhado (== fazer JSON dele), mas falha ao encontrar JavassistLazyInitializer em vez do objeto normal. Este é o erro que você vê. Agora, como resolver isso?
Conforme sugerido pelo CP510 anteriormente, uma opção é suprimir o erro por esta linha de configuração:
Mas isso é lidar com os sintomas, não com a causa . Para resolvê-lo com elegância, você precisa decidir se precisa ou não desse objeto em JSON?
Se você precisar do objeto em JSON, remova a
FetchType.LAZY
opção do campo que o causa (também pode ser um campo em algum objeto aninhado, não apenas na entidade raiz que você está buscando).Se não precisar do objeto em JSON, anote o getter deste campo (ou o próprio campo, se também não precisar aceitar valores de entrada) com
@JsonIgnore
, por exemplo:// this field will not be serialized to/from JSON @JsonIgnore private NestedType secret;
Se você tiver necessidades mais complexas (por exemplo, regras diferentes para controladores REST diferentes usando a mesma entidade), você pode usar visualizações ou filtragem jackson ou, para casos de uso muito simples, buscar objetos aninhados separadamente.
fonte
RangeError: Maximum call stack size exceeded
Você pode usar o módulo adicional para Jackson que lida com o carregamento lento do Hibernate.
Mais informações em https://github.com/FasterXML/jackson-datatype-hibernate que suportam hibernate 3 e 4 separadamente.
fonte
Acho que o problema é a maneira como você recupera a entidade.
Talvez você esteja fazendo algo assim:
Tente usar o método em
get
vez deload
O problema é que com o método load você obtém apenas um proxy, mas não o objeto real. O objeto proxy não possui as propriedades já carregadas, portanto, quando a serialização ocorre, não há propriedades a serem serializadas. Com o método get, você realmente obtém o objeto real, esse objeto poderia de fato ser serializado.
fonte
funciona para mim
por exemplo
fonte
Existem duas maneiras de resolver o problema.
Caminho 1 :
Adicionar
spring.jackson.serialization.fail-on-empty-beans=false
em application.propertiesCaminho 2 :
Use
join fetch
na consulta JPQL para recuperar dados do objeto pai, veja abaixo:fonte
Adicione esta anotação à classe de entidade (modelo) que funciona para mim para causar carregamento lento por meio do objeto proxy de hibernação.
fonte
Esta exceção
recebendo porque, espero que sim, você está enviando a saída de resposta como um objeto Serializable.
Este é um problema que ocorre na primavera. Para superar esse problema, envie o objeto POJO como saída de resposta.
Exemplo:
Aula POJO:
No controlador, converta os campos de objeto serilizáveis em campos de classe POJO e retorne a classe pojo como saída.
fonte
No Hibernate 5.2 e superior, você pode remover o proxy do Hibernate conforme abaixo, ele fornecerá o objeto real para que você possa serializá-lo corretamente:
fonte
Hibernate.initialize
antemão.Para Hibernate, você pode usar o projeto jackson-datatype-hibernate para acomodar a serialização / desserialização JSON com objetos carregados lentamente.
Por exemplo,
fonte
can't parse JSON. Raw result:
. Qualquer ajuda?A solução é inspirada na solução abaixo da @marco. Eu também atualizei sua resposta com esses dados.
O problema aqui é sobre o carregamento lento dos subobjetos, onde Jackson só encontra proxies de hibernação, em vez de objetos completos.
Portanto, ficamos com duas opções - Suprimir a exceção, como feito acima na resposta mais votada aqui, ou certifique-se de que os objetos LazyLoad sejam carregados.
Se você escolher a última opção, a solução seria usar a biblioteca jackson-datatype e configurar a biblioteca para inicializar as dependências de carregamento lento antes da serialização.
Eu adicionei uma nova classe de configuração para fazer isso.
}
@Primary
certifica-se de que nenhuma outra configuração de Jackson seja usada para inicializar qualquer outro bean.@Bean
é como de costume.module.enable(Hibernate5Module.Feature.FORCE_LAZY_LOADING);
é habilitar o carregamento lento das dependências.Cuidado - observe o impacto no desempenho. às vezes, a busca EAGER ajuda, mas mesmo que você a torne ansiosa, ainda precisará desse código, porque os objetos proxy ainda existem para todos os outros mapeamentos, exceto
@OneToOne
PS: Como um comentário geral, eu desencorajaria a prática de enviar objetos de dados inteiros de volta na resposta Json. Deve-se usar Dto's para essa comunicação e usar algum mapeador como mapstruct para mapeá-los. Isso o salva de brechas de segurança acidentais, bem como da exceção acima.
fonte
Tenho o mesmo problema agora. verifique se você corrige a busca no preguiçoso com um @jsonIQgnore
Basta excluir o "(fetch = ...)" ou a anotação "@jsonIgnore" e vai funcionar
fonte
Ou você pode configurar o mapeador como:
// configuração personalizada para carregamento lento
e configurar o mapeador:
fonte
Pode ser o relacionamento de entidade do Hibernate causando o problema ... simplesmente pare o carregamento lento dessa entidade relacionada ... por exemplo ... Resolvi abaixo definindo lazy = "false" para customerType.
fonte
Eu mudei (na classe de modelo de anotação)
para
e funcionou de uma maneira bonita ...
Adoro.
fonte
fetch
estratégia em um modelo tem várias consequências no desempenho. Com essa mudança, você está trazendo muito mais dados do banco de dados. Pode ser uma solução válida, mas primeiro é necessário um estudo de desempenho.Este é um problema com Jackson. Para evitar isso, instrua Jackson a não serializar relacionamento aninhado ou classe aninhada.
Veja o exemplo a seguir. Classe de endereço mapeada para as classes City , State e Country e o próprio Estado está apontando para Country e Country apontando para Region. Quando seus valores de endereço forem obtidos por meio da API REST de boot do Spring, você receberá o erro acima. Para evitar isso, basta serializar a classe mapeada (que reflete o nível um JSON) e ignorar os relacionamentos aninhados com
@JsonIgnoreProperties(value = {"state"})
,@JsonIgnoreProperties(value = {"country"})
e@JsonIgnoreProperties(value = {"region"})
Isso evitará a exceção Lazyload junto com o erro acima. Use o código abaixo como exemplo e mude suas classes de modelo.
Address.java
City.java
State.java
Country.java
fonte
Experimentar
implements interface Serializable
fonte