3 Replies Latest reply on Jan 19, 2009 11:52 AM by Chris Moerz

    LazyInitializationException and PAGE scope

    Grigoriy Tkachuk Newbie

      Hi!
      I trying to create administration page for creating gallery. In one of my page I use
      rich:fileupload component. But when I upload image and try add it to my Gallery object I catch:


      14:45:18,297 WARN  [lifecycle] failed to lazily initialize a collection of role: ru.makingpages.chicago.entity.gallery.Gallery.images, no session or session was closed
      
      



      This is my Gallery.java:


      @Entity
      @NamedQueries({
              @NamedQuery(name = "findAllGalleries", query = "select gal from Gallery gal order by gal.date desc")
      })
      public class Gallery implements Serializable {
          private long id;
          private String title;
          private List<Image> images;
          private Date date;
      
          @Id
          @GeneratedValue
          public long getId() {
              return id;
          }
      
          public void setId(long id) {
              this.id = id;
          }
      
          public String getTitle() {
              return title;
          }
      
          public void setTitle(String title) {
              this.title = title;
          }
      
          @OneToMany(mappedBy = "gallery", fetch = FetchType.LAZY)
          public List<Image> getImages() {
              return images;
          }
      
          public void setImages(List<Image> images) {
              this.images = images;
          }
      
          public Date getDate() {
              return date;
          }
      
          public void setDate(Date date) {
              this.date = date;
          }
      
          @Transient
          public void addImage(Image image) {
              images.add(image);
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
      
              Gallery gallery = (Gallery) o;
      
              if (id != gallery.id) return false;
              if (date != null ? !date.equals(gallery.date) : gallery.date != null) return false;
              if (images != null ? !images.equals(gallery.images) : gallery.images != null) return false;
              if (title != null ? !title.equals(gallery.title) : gallery.title != null) return false;
      
              return true;
          }
      
          @Override
          public int hashCode() {
              int result = (int) (id ^ (id >>> 32));
              result = 31 * result + (title != null ? title.hashCode() : 0);
              result = 31 * result + (images != null ? images.hashCode() : 0);
              result = 31 * result + (date != null ? date.hashCode() : 0);
              return result;
          }
      }
      
      



      This is my Seam Component:


      @Name("galleryHome")
      @Scope(ScopeType.PAGE)
      public class GalleryHome {
          @In
          private EntityManager entityManager;
      
          @Logger
          Log log;
      
          private Long galleryId;
      
          private Gallery instance;
      
          @RequestParameter
          public void setGalleryId(Long id) {
              galleryId = id;
              if (id != null) {
                  try {
                      instance = entityManager.find(Gallery.class, id);
                  } catch (Exception ex) {
                      log.error(ex);
                  }
      
              }
          }
      
          public Gallery getInstance() {
              return instance;
          }
      
          public void setInstance(Gallery instance) {
              this.instance = instance;
          }
      
          public Long getGalleryId() {
              return galleryId;
          }
      
      
          public void persist() {
              //To change body of implemented methods use File | Settings | File Templates.
          }
      
          public void update() {
              entityManager.merge(instance);
          }
      
      
          public void processUpload(UploadEvent uploadEvent) {
              try {
                  org.richfaces.model.UploadItem item = uploadEvent.getUploadItem();
                  ru.makingpages.chicago.entity.gallery.Image uploadedImage = new ru.makingpages.chicago.entity.gallery.Image();
                  Image smallImage = buildImage(item.getFile(), 460, 345);
                  Image miniImage = buildImage(item.getFile(), 75, 100);
                  uploadedImage.setContentType(item.getContentType());
                  uploadedImage.setDate(new Date());
                  uploadedImage.setSmallImage(smallImage.getImage());
                  uploadedImage.setMiniImage(miniImage.getImage());
                  instance.addImage(uploadedImage);
                  log.info("fileUploaded");
              } catch (Exception ex) {
                  log.error(ex);
              }
          }
      
      
          private Image buildImage(File file, int width, int height) {
              Image image = new Image();
              try {
                  image.setInput(file);
                  if (image.getHeight() > image.getWidth())
                      image.scaleToHeight(height);
                  else
                      image.scaleToWidth(width);
              } catch (IOException e) {
                  log.error(e);
                  return null;
              }
              return image;
          }
      
      
      }
      


      and my view:


       <h:form id="editForm">
                  <div>
                      <h:panelGrid columns="1">
      
                          <ui:define name="label">#{messages['label.title']}</ui:define>
                          <h:inputText id="title" value="#{galleryHome.instance.title}" size="70" required="true"/>
                          <rich:fileUpload fileUploadListener="#{galleryHome.processUpload}"
                                           addControlLabel="#{messages['fileupload.upload']}"
                                           stopControlLabel="#{messages['fileupload.stop']}"
                                           stopEntryControlLabel="#{messages['fileupload.stop']}"
                                           immediateUpload="true"
                                           listHeight="150px"
                                           autoclear="false"
                                           maxFilesQuantity="99"
                                           acceptedTypes="gif, jpeg, jpg, png">
                              <a:support event="onuploadcomplete" reRender="graphics"/>
                          </rich:fileUpload>
                      </h:panelGrid>
                      <a:outputPanel id="graphics">
                          <ui:repeat var="img" value="#{galleryHome.instance.images}">
                              <s:graphicImage value="#{img.miniImage}"/>
      
                              <p/>
                          </ui:repeat>
                      </a:outputPanel>
                  </div>
                  <br/>
                  <rich:separator/>
                 
      
                  <h:commandButton value="#{messages['button.update']}"
                                   action="#{galleryHome.update}"/>
      
              </h:form>
      



      I use JBoss Seam 2.1GA


      Please somebody help me :)

        • 1. Re: LazyInitializationException and PAGE scope
          Chris Moerz Newbie

          I'm not sure if that's really gonna help you, but I once had a problem with some lazy loading exception and what fixed it in my case was the following: I too was using @In to inject my entitymanager, instead I switched to


          @PersistenceContext(type=EXTENDED)
          EntityManager entityManager;
          



          Then it worked flawlessly. Maybe that'll fix it in your case too. I'm not sure though, since I don't see in your code why the entityManager would want to load something with a name role. It rather looks like you haven't properly set up Seam's identity management?


          good luck
          chris

          • 2. Re: LazyInitializationException and PAGE scope
            Grigoriy Tkachuk Newbie

            I can't add PersistenceContext annotation because it's plain seam component. thank you for your response :)
            Maybe you have more ideas about it :). I triyng convert it's component to EntityHome but it starting throws EntityManager is closed

            • 3. Re: LazyInitializationException and PAGE scope
              Chris Moerz Newbie

              I didn't really look that close the first time, after quickly browsing through your code snippets I wonder - don't you want to put that into a conversation context? I mean, you're uploading stuff and that should probably be stateful anyways, right?


              I'd try going


              @Scope(ScopeType.CONVERSATION)
              @Stateful
              



              on your GalleryHome. After all you want to manipulate that data across a form submit; I've got a strange feeling that doing what you're trying to do isn't going to work on a stateless bean.


              chris