Как исправить "LazyInitializationException", с которым я сталкиваюсь? - PullRequest
0 голосов
/ 03 февраля 2019

Надеюсь, вы сможете помочь мне перестать бить меня головой о стену.

Вот моя проблема, после многих дней исследований на многих форумах я не нашел ни одного совместимого ответа с этой проблемой.Я сталкиваюсь.

У меня есть org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.supinfo.suppicture.entity.User.pictures, no session or session was closed, который кажется известным исключением, но все же сводит меня с ума ...

Я пытался заставить Eager загружаться вместо ленивогозагружается, но все еще имеет ту же проблему.

Вот мои классы:

category.java

@Entity
@Table(name = "category")
@XmlRootElement
public class Category{

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;

private String Name;

@OneToMany(mappedBy = "category")
private Collection<Picture> pictures;

(getters and setters)

user.java

@Entity
@Table(name = "user")
@XmlRootElement
public class User {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;

private String username;

private String password;

private String firstName;

private String lastName;

private String phoneNumber;

private String postalAddress;

private String email;

@OneToMany(mappedBy = "author")
private Collection<Picture> pictures;

    (getters and setters)

picture.java

@Entity
@Table(name = "picture")
@XmlRootElement
public class Picture {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;

private String name;

private String description;

@Column(columnDefinition="longblob")
private byte[] image;

private Date dateOfPublish;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "category_id")
private Category category;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User author;

    (getters and setters)

И вот пример того, как я пытаюсь получить свои фотографии в базе данных (которая является единственной, у которой есть внешние ключи)

@Override
public List<Picture> getAllPictures() {
    EntityManager em = emf.createEntityManager();
    try {
        CriteriaQuery<Picture> criteriaQuery = em.getCriteriaBuilder()
            .createQuery(Picture.class);
        criteriaQuery.from(Picture.class);
        return em.createQuery(criteriaQuery).getResultList();
    } finally {
        em.close();
    }
}

Наконец, называется так:

@Path("/picture")
public class PictureController {

@GET
@Path("/all") @Produces(MediaType.APPLICATION_JSON)
public List<Picture> getAllPictures(){
    return DaoFactory.getPictureDao().getAllPictures();
}

Полная трассировка стека исключений:

févr.03, 2019 16:38:48 org.hibernate.LazyInitializationException GRAVE: не удалось лениво инициализировать коллекцию ролей: com.supinfo.suppicture.entity.User.pictures, ни один сеанс или сеанс не был закрыт org.hibernate.LazyInitializationException: не удалосьчтобы лениво инициализировать коллекцию ролей: com.supinfo.suppicture.entity.User.pictures, ни один сеанс или сеанс не был закрыт в org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException (AbstractPersistentCollection.java:383) в org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected (AbstractPersistentCollection.java:375) в org.hibernate.collection..PersistentBag.iterator (PersistentBag.java:272) в com.sun.xml.internal.bind.v2.runtime.reflect.Lister $ CollectionLister.iterator (Lister.java:266) в com.sun.xml.internal.bind.v2.runtime.reflect.Lister $ CollectionLister.iterator (Lister.java:253) в com.sun.xml.internal.bind.v2.runtime.property.ArrayElementProperty.serializeListBody (ArrayElementProperty.java:118) в com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty.serializeBody (ArrayERProperty.java:144) в com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody (ClassBeanInfoImpl.java:345) в com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType (XMLSerializer.java:681) в com.sun.xin.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody (SingleElementNodeProperty.java:143) в com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody (ClassBeanInfoImpl.java.s3: at.internal.bind.v2.runtime.XMLSerializer.childAsSoleContent (XMLSerializer.java:578) в com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot (ClassBeanInfoImpl.java:326) в com.sun.x.internal.bind.v2.runtime.XMLSerializer.childAsRoot (XMLSerializer.java:479) в com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write (MarshallerImpl.java:308) в com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal (MarshallerImpl.java:163) на com.sun.jersey.json.impl.provider.entity.JSONListElementProvider.writeList (JSONListElementProvider.java:145) на com.sun.jersey.cist.providejjwriteTo (AbstractListElementProvider.java:264) в com.sun.jersey.spi.container.ContainerResponse.write (ContainerResponse.java:306) в com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest: WebApplication:1448) на com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest (WebApplicationImpl.java:1360) на com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest (WebApplicationImpl.java:13).sun.jersey.spi.container.servlet.WebComponent.service (WebComponent.java:416) в com.sun.jersey.spi.container.servlet.ServletContainer.service (Servle)tContainer.java:538)на com.sun.jersey.spi.container.servlet.ServletContainer.service (ServletContainer.java:716) на javax.servlet.http.HttpServlet.service (HttpServlet.java:725) на org.apache.catalina.cter.Aplication.internalDoFilter (ApplicationFilterChain.java:291) в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:206) в org.apache.tomcat.websocket.server.WsFilter.doFilter at (WF).org.apache.catalina.core.StandardWrapperValve.java:219) в org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:106) в org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.jap.atina) at50.core.StandardHostValve.invoke (StandardHostValve.java:142) в org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:79) в org.apache.catalina.valves.AbstractAccessLogValve.invoke (AbstractAccessLogValve.java:610) в org.apache.catalina.core.StandardEngineValve.invoke88 или в org (стандартная версия).apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:537) в org.apache.coyote.http11.AbstractHttp11Processor.process (AbstractHttp11Processor.java:1081) в org.apache.coyote.AcessstractProand Protocol $.java: 658) в org.apache.coyote.http11.Http11NioProtocol $ Http11ConnectionHandler.process (Http11NioProtocol.java:222) в org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun (NioEnd): точка доступаorg.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.run (NioEndpoint.java:1523) в java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1149) в java.util.concurrent.ecread $.выполнить (ThreadPoolExecutor.java:624) в org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run (TaskThread.java:61) на java.lang.Thread.run (Thread.java:748)

févr.03, 2019 16:38:48 org.apache.catalina.core.StandardWrapperValve вызывают GRAVE: «Servlet.service ()» для сервлета-джерси-сервлета исключение org.hibernate.LazyInitialization исключение org.hibernate.LazyInitializationException: не удалось лениво инициализировать коллекциюof role: com.supinfo.suppicture.entity.User.pictures, ни один сеанс или сеанс не был закрыт в org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException (AbstractPersistentCollection.java:383) в org.hibernate.collection.AbstractPersistentCistingTollectionNollectionFollectionTollection..java: 375) в org.hibernate.collection.AbstractPersistentCollection.initialize (AbstractPersistentCollection.java:368) в org.hibernate.collection.AbstractPersistentCollection.read (AbstractPersistentCollection.java:111) в org.hibernate.Bite.PersistentBag.java:272) на com.sun.xml.internal.bind.v2.runtime.reflect.Lister $ CollectionLister.iterator (Lister.java:266) на com.sun.xml.internal.bind.v2.runtime.reflect.Lister $ CollectionLister.iterator (Lister.java:253) в com.sun.xml.internal.bind.v2.runtime.property.ArrayElementProperty.serializeListBody (ArrayElementProperty.java:118) вcom.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty.serializeBody (ArrayERProperty.java:144) в com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody (ClassBeanInfoImpl.j) в com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType (XMLSerializer.java:681) в com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody (SingleElementjperPro): 143) at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody (ClassBeanInfoImpl.java:345)в com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsSoleContent (XMLSerializer.java:578) в com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot (ClassBeanInfoImpl.java:32в com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot (XMLSerializer.java:479) в com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write (MarshallerImpl.java:308)в com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal (MarshallerImpl.java:163) в com.sun.jersey.json.impl.provider.entity.JSONListElementProvider.writeList (JSONListElementProvider.j.в com.sun.jersey.core.provider.jaxb.AbstractListElementProvider.writeTo (AbstractListElementProvider.java:264) в com.sun.jersey.spi.container.ContainerResponse.write (ContainerResponse.java:306) в com.sun.server.impl.application.WebApplicationImpl._handleRequest (WebApplicationImpl.java:1448) в com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest (WebApplicationImpl.java:1360) в com.sun.jersey.ver.impl.application.WebApplicationImpl.handleRequest (WebApplicationImpl.java:1350) на com.sun.jersey.spi.container.servlet.WebComponent.service (WebComponent.java:416) на com.sun.jersey.spi.container.servlet.ServletContainer.service (ServletContainer.java:538) по адресу com.sun.jersey.spi.container.servlet.ServletContainer.service (ServletContainer.java:716) по адресу javax.servlet.http.HttpServlet.service (HttpShtv725) в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:291) в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:206) в org.serb..WsFilter.doFilter (WsFilter.java:52) в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:239) в org.apache.catalina.core.ApplicationFilterChain.jF: (ApplicationFilterChain.jF) (org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:219) в org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:106) по адресу org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:506) по адресу org.apache.catalina.core.StandardHostValve.invalve или org)..apache.catalina.valves..java: 88) в org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:537) в org.apache.coyote.http11.AbstractHttp11Processor.process (AbstractHttp11Processor.java:1081) в org.apache.coy.AbstractProtocol $ AbstractConnectionHandler.process (AbstractProtocol.java:658) по адресу org.apache.coyote.http11.Http11NioProtocol $ Http11ConnectionHandler.process (Http11NioProtocol.java:222) по адресу org.apache.tomcat.util.net.NocketSoft ()NioEndpoint.java:1566) в org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.run (NioEndpoint.java:1523) в java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1149) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:6g: 6:.tomcat.util.чтобы помочь мне решить проблему.Заранее спасибо.

Потерянный разработчик.

Ответы [ 4 ]

0 голосов
/ 04 февраля 2019

Спасибо Сантошу Баладжи за трюк;)

0 голосов
/ 04 февраля 2019
  • Кажется, сеанс не открыт или транзакция отсутствует.Вам не хватает начала и конца транзакции.
  • Есть два варианта: либо ваш менеджер сам выполняет транзакцию, либо какой-то менеджер транзакций делает это в каком-то контейнере.
  • Неидиома управляемой среды

    EntityManager em = emf.createEntityManager ();EntityTransaction tx = null;try {tx = em.getTransaction (); tx.begin ();

    // выполнить некоторую работу ... введите код здесь tx.commit (); } catch (RuntimeException e) {if (tx! = null && tx.isActive ()) tx.rollback () ;бросить е;// или отображаем сообщение об ошибке} finally {em.close ();}

  • подробнее здесь: https://docs.jboss.org/hibernate/orm/4.0/hem/en-US/html/transactions.html
0 голосов
/ 04 февраля 2019

Давайте разделим этот шаг на шаг

1) Ваш веб-контроллер в Джерси вызывает ваш метод dao для получения списка картинок (без ошибок)

2) Теперь ваш слой dao получает данныеиз базы данных (без ошибок)

3) Значение возвращается в метод контроллера вашего веб-сервиса (без ошибок)

4) Но вы используете автоматический преобразователь json для преобразования данных объекта в json.Ваши фотографии имеют данные, связанные с пользователем.Когда json converter пытается получить данные пользователя, значение равно нулю, потому что ваша транзакция уже завершилась, что приводит к исключению.Попробуйте игнорировать категорию и пользовательские поля во время преобразования json, как показано ниже.

@JsonIgnore
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "category_id")
private Category category;

@JsonIgnore
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User author;

5) Не следует использовать объект рисунка непосредственно для преобразования json, так как это приведет к циклической избыточности (бесконечный цикл).Попробуйте создать еще один класс-оболочку рисунка для обработки этого сценария

Изображение -> Пользователь -> Изображение -> Пользователь (циклическая избыточность)

Поэтому для исправления этого создайте три класса-оболочки

public class PictureWrapper 
{
    private int id;

    private String name;

    private String description;

    private byte[] image;

    private Date dateOfPublish;

    private CategoryWrapper category;

    private UserWrapper author;
}


public class UserWrapper
{
    private int id;

    private String username;

    private String password;

    private String firstName;

    private String lastName;

    private String phoneNumber;

    private String postalAddress;

    private String email;
}

public class CategoryWrapper
{
    private int id;

    private String Name;
}

Затем измените метод getAllPictures на следующий

public List<PictureWrapper> getAllPictures() 
{
    List<PictureWrapper> resultList = new ArrayList<PictureWrapper>();
    EntityManager em = emf.createEntityManager();
    try 
    {
        CriteriaQuery<Picture> criteriaQuery = em.getCriteriaBuilder().createQuery(Picture.class);
        criteriaQuery.from(Picture.class);
        List<Picture> list =  em.createQuery(criteriaQuery).getResultList();
    if(list != null && list.size() != 0)
    {
        for(Picture picture : list)
        {
            PictureWrapper pictureWrapper = new PictureWrapper();
            //Load data from picture to picture wrapper with user and category
            resultList.add(pictureWrapper);
        }
    }
    } 
    finally 
    {
        em.close();
    }
    return resultList;
}
0 голосов
/ 03 февраля 2019

Вам нужно украсить OneToMany свойства user.pictures и category.pictures с помощью стратегии извлечения EAGER.

class Category {
    @OneToMany(mappedBy = "category", fetch = FetchType.EAGER)
    Collection<Picture> pictures;
}

class User {
    @OneToMany(mappedBy = "author", fetch = FetchType.EAGER)
    Collection<Picture> pictures;
}

В качестве примечания, вам на самом деле не нужно украшатьManyToOne свойств со стратегией выборки EAGER, так как это поведение по умолчанию .

...