Estoy trabajando en SpringMVC
, Hibernate
y JSON
pero estoy consiguiendo este error.
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 mi entidad a continuación
@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 puedo resolver esto?
Respuestas:
Tuve un problema similar con la carga diferida a través del objeto proxy de hibernación. Lo solucioné anotando la clase que tenía propiedades privadas cargadas de forma diferida con:
Supongo que puede agregar las propiedades en su objeto proxy que rompe la serialización JSON a esa anotación.
El problema es que las entidades se cargan de forma perezosa y la serialización ocurre antes de que se carguen por completo.
fuente
Solo para agregar esto, me encontré con el mismo problema, pero las respuestas proporcionadas no funcionaron. Lo arreglé tomando la sugerencia de la excepción y agregando al archivo application.properties ...
Estoy usando Spring Boot v1.3 con Hibernate 4.3
Ahora serializa todo el objeto y los objetos anidados.
EDITAR: 2018
Dado que esto todavía recibe comentarios, lo aclararé aquí. Esto absolutamente solo oculta el error. Las implicaciones de rendimiento están ahí. En ese momento, necesitaba algo para entregar y trabajar en ello más tarde (lo que hice al dejar de usar Spring). Entonces, sí, escuche a alguien más si realmente quiere resolver el problema. Si solo quiere que desaparezca por ahora, continúe y use esta respuesta. Es una idea terrible, pero diablos, podría funcionar para ti. Para el registro, nunca volví a tener un bloqueo o problema después de esto. Pero probablemente sea la fuente de lo que terminó siendo una pesadilla de rendimiento de SQL.
fuente
"handler":{},"hibernateLazyInitializer":{}
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
Como se sugirió correctamente en respuestas anteriores, la carga diferida significa que cuando recupera su objeto de la base de datos, los objetos anidados no se recuperan (y pueden recuperarse más tarde cuando sea necesario).
Ahora Jackson intenta serializar el objeto anidado (== hacer JSON fuera de él), pero falla cuando encuentra JavassistLazyInitializer en lugar del objeto normal. Este es el error que ves. Ahora bien, ¿cómo solucionarlo?
Como sugirió anteriormente CP510, una opción es suprimir el error mediante esta línea de configuración:
Pero se trata de tratar los síntomas, no la causa . Para resolverlo con elegancia, debe decidir si necesita este objeto en JSON o no.
Si necesita el objeto en JSON, elimine la
FetchType.LAZY
opción del campo que lo causa (también podría ser un campo en algún objeto anidado, no solo en la entidad raíz que está obteniendo).Si no necesita el objeto en JSON, anote el captador de este campo (o el campo en sí, si tampoco necesita aceptar valores entrantes) con
@JsonIgnore
, por ejemplo:// this field will not be serialized to/from JSON @JsonIgnore private NestedType secret;
Si tiene necesidades más complejas (por ejemplo, diferentes reglas para diferentes controladores REST que usan la misma entidad), puede usar vistas o filtrado de jackson o, para un caso de uso muy simple, buscar objetos anidados por separado.
fuente
RangeError: Maximum call stack size exceeded
Puede usar el módulo adicional para Jackson que maneja la carga diferida de Hibernate.
Más información en https://github.com/FasterXML/jackson-datatype-hibernate que admite hibernación 3 y 4 por separado.
fuente
Creo que el problema es la forma en que recuperas la entidad.
Tal vez estés haciendo algo como esto:
Intente usar el método en
get
lugar deload
El problema es que con el método de carga solo se obtiene un proxy pero no el objeto real. El objeto proxy no tiene las propiedades ya cargadas, por lo que cuando ocurre la serialización, no hay propiedades para serializar. Con el método get, realmente obtiene el objeto real, este objeto podría de hecho ser serializado.
fuente
esto funciona para mi
p.ej
fuente
Hay dos formas de solucionar el problema.
Camino 1 :
Agregar
spring.jackson.serialization.fail-on-empty-beans=false
a application.propertiesCamino 2 :
Úselo
join fetch
en la consulta JPQL para recuperar datos del objeto principal, consulte a continuación:fuente
Agregue esta anotación a la clase de entidad (modelo) que funciona para mí, esto causa una carga diferida a través del objeto proxy de hibernación.
fuente
Esta excepción
obteniendo porque, espero que sí, estás enviando una salida de respuesta como un objeto serializable.
Este es un problema que ocurre en primavera. Para superar este problema, envíe el objeto POJO como salida de respuesta.
Ejemplo:
Clase POJO:
En el controlador, convierta los campos del objeto serilizable en campos de clase POJO y devuelva la clase pojo como salida.
fuente
En Hibernate 5.2 y superior, puede eliminar el proxy de hibernación como se muestra a continuación, le dará el objeto real para que pueda serializarlo correctamente:
fuente
Hibernate.initialize
antemano.Para Hibernate, puede usar jackson-datatype-hibernate para acomodar la serialización / deserialización JSON con objetos de carga diferida.
Por ejemplo,
fuente
can't parse JSON. Raw result:
. ¿Alguna ayuda?La solución está inspirada en la siguiente solución de @marco. También he actualizado su respuesta con estos datos.
El problema aquí es sobre la carga diferida de los subobjetos, donde Jackson solo encuentra proxies de hibernación, en lugar de objetos completos.
Así que nos quedan dos opciones: suprimir la excepción, como se hizo anteriormente en la respuesta más votada aquí, o asegurarse de que los objetos LazyLoad estén cargados.
Si elige optar por la última opción, la solución sería usar la biblioteca jackson-datatype y configurar la biblioteca para inicializar las dependencias de carga diferida antes de la serialización.
Agregué una nueva clase de configuración para hacer eso.
}
@Primary
se asegura de que no se utilice ninguna otra configuración de Jackson para inicializar otros beans.@Bean
es como de costumbre.module.enable(Hibernate5Module.Feature.FORCE_LAZY_LOADING);
es habilitar la carga diferida de las dependencias.Precaución: esté atento a su impacto en el rendimiento. a veces, EAGER fetch ayuda, pero incluso si lo hace ansioso, todavía necesitará este código, porque los objetos proxy todavía existen para todas las demás asignaciones excepto
@OneToOne
PD: Como comentario general, desalentaría la práctica de enviar el objeto de datos completo de vuelta en la respuesta de Json. Uno debería usar Dto's para esta comunicación y usar algún mapeador como maptruct para mapearlos. Esto le evita lagunas de seguridad accidentales, así como la excepción anterior.
fuente
Tengo el mismo problema ahora mismo. compruebe si corrige la recuperación en lazy con un @jsonIQgnore
Simplemente elimine "(fetch = ...)" o la anotación "@jsonIgnore" y funcionará
fuente
O puede configurar el asignador como:
// configuración personalizada para carga diferida
y configurar mapeador:
fuente
Podría ser su relación de entidad de Hibernate la que causa el problema ... simplemente detenga la carga diferida de esa entidad relacionada ... por ejemplo ... Lo resolví a continuación estableciendo lazy = "false" para customerType.
fuente
Cambié (en la clase de modelo de anotación)
a
y funcionó de manera bonita ...
Quiéralo.
fuente
fetch
estrategia de un modelo tiene varias consecuencias en el rendimiento. Con este cambio, traerá muchos más datos de la base de datos. Puede ser una solución válida, pero primero se necesita un estudio de desempeño.Este es un problema con Jackson. Para evitar esto, indique a Jackson que no serialice la relación anidada o la clase anidada.
mira el siguiente ejemplo. La clase de dirección se asigna a las clases Ciudad , Estado y País , y el propio Estado apunta al País y al País apunta a la Región. Cuando obtenga los valores de dirección a través de la API REST de Spring boot, obtendrá el error anterior. Para evitarlo, simplemente serialice la clase asignada (que refleja JSON de nivel uno) e ignore las relaciones anidadas con
@JsonIgnoreProperties(value = {"state"})
,@JsonIgnoreProperties(value = {"country"})
y@JsonIgnoreProperties(value = {"region"})
Esto evitará la excepción Lazyload junto con el error anterior. Utilice el siguiente código como ejemplo y cambie las clases de su modelo.
Dirección.java
City.java
State.java
Country.java
fuente
Tratar
implements interface Serializable
fuente