restcontroller requestmapping requestbody mvc example ejemplo json spring hibernate hql jackson

json - requestmapping - spring mvc ejemplo



Spring MVC 3.1.2+Jackson 2: LazyInitializationException al inicializar una colección de forma perezosa: no se cerró sesión ni sesión (3)

Intente utilizar OpenSessionInViewFilter mientras esto es para acceder a los campos inicializados perezosos en su vista, puede mantener la sesión abierta para que Jackson pueda acceder a la colección.

OpenSessionInViewFilter vincula una sesión de Hibernate a la OpenSessionInViewFilter para todo el procesamiento de la solicitud. Diseñado para el patrón "Abrir sesión en vista", es decir, para permitir la carga diferida en vistas web a pesar de que las transacciones originales ya se han completado.

En Web.xml

<filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

Documentación API

Me estoy volviendo loco con un error que estoy teniendo con Spring MVC 3.1.2 y Jackson 2.

Tengo la siguiente clase de modelo:

@Entity @Table(name = "USER") @JsonIgnoreProperties(ignoreUnknown=true) public class User implements Serializable { @Id @SequenceGenerator(name = "USER_ID", sequenceName = "USER_ID_SEQ", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_ID") private Long id; @Column(length = 50, nullable = false) private String firstName; @Column(length = 50, nullable = false) private String lastName; @ManyToMany @JoinTable(name = "FRIENDS", joinColumns = @JoinColumn(name = "personId"), inverseJoinColumns = @JoinColumn(name = "friendId") ) @JsonManagedReference private List<User> friends; @ManyToMany @JoinTable(name="FRIENDS", joinColumns=@JoinColumn(name="friendId"), inverseJoinColumns=@JoinColumn(name="personId") ) @JsonIgnore private List<User> friendOf; // Other attributes and methods... }

Cuando obtengo una única instancia de Usuario, Jackson la serializa correctamente. Pero cuando trato de obtener una instancia de Usuario que contenga amigos, se lanza la siguiente excepción:

org.hibernate.LazyInitializationException: no se pudo inicializar de forma lenta una colección de roles: com.frooid.model.User.friends, no se cerró ninguna sesión o sesión

Obtengo esta instancia usando un solo HQL:

select u from User u left join fetch u.friends f where u.id = :id

¡Gracias a todos!


Muchas asociaciones tienen una carga lenta por defecto. Esto significa que los amigos de tus usuarios solo se cargarán desde la base de datos al invocar un método de la lista de friends .

Esta carga lenta solo puede ocurrir mientras la sesión utilizada para cargar al usuario está abierta. Por lo tanto, si devuelve al usuario de su método transaccional sin la lista de amigos cargada, la sesión se cerrará e intentar cargar la lista de amigos dará lugar a la excepción que está recibiendo.

Por lo tanto, si el cliente necesita que se cargue la lista de contactos, puede buscar a los amigos que usan HQL o forzar la inicialización de la lista, dentro del método de servicio, llamando a un método en la lista o llamando a Hibernate.initialize(user.getFriends()) .

EDITAR: ya que tiene una búsqueda en su HQL, debería funcionar. Otro problema es que la asociación bidireccional se asigna dos veces: una vez en el campo de friends , y una vez en el campo friendOf . Una de esas asociaciones debe marcarse como la inversa de la otra utilizando el atributo mappedBy :

@ManyToMany(mappedBy = "friends") @JsonIgnore private List<User> friendOf;


Tuve un problema similar. El enfoque fue crear una nueva clase (vista) y agregar esta clase en @JsonView({NewClass1.class,NewClass2.class}) en cada propiedad, en la Entidad donde se definen sus propiedades. Puede elegir las variables que desea cargar como parte de su respuesta e incluir la clase en @JsonView . ¡Tan simple como eso!