views:

408

answers:

2

Right so i am working with hibernate gilead and gwt to persist my data on users and files of a website. my users have a list of file locations. i am using annotations to map my classes to the database. I am getting a org.hibernate.LazyInitializationException when i try to add file locations to the list that is held in the user class.

this is a method below that is overridden from a external file upload servlet class that i am using. when the file uploads it calls this method.

the user1 is loaded from the database elsewhere. the exception occurs at user1.getFileLocations().add(fileLocation); . I dont understand it really at all.! any help would be great. the stack trace of the error is below

public String executeAction(HttpServletRequest request,
            List<FileItem> sessionFiles) throws UploadActionException {
          for (FileItem item : sessionFiles) {
              if (false == item.isFormField()) {
                try {
                    YFUser user1 = (YFUser)getSession().getAttribute(SESSION_USER);

                    // This is the location where a file will be stored

                    String fileLocationString = "/Users/Stefano/Desktop/UploadedFiles/" + user1.getUsername();
                    File fl = new File(fileLocationString);
                    fl.mkdir();
                    // so here i will create the a file container for my uploaded file

                  File file = File.createTempFile("upload-", ".bin",fl);


                  // this is where the file is written to disk

                  item.write(file);

                  // the FileLocation object is then created
                  FileLocation fileLocation = new FileLocation();
                  fileLocation.setLocation(fileLocationString);
                  //test
                  System.out.println("file path = "+file.getPath());



                  user1.getFileLocations().add(fileLocation);

                  //the line above is where the exception occurs 

                } catch (Exception e) {
                  throw new UploadActionException(e.getMessage());
                }
              }
              removeSessionFileItems(request);
            }
            return null;
    }  

//This is the class file for a Your Files User

@Entity
@Table(name = "yf_user_table")
public class YFUser implements Serializable,ILightEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id",nullable = false)
private int userId;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Column(name = "email")
private String email;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "USER_FILELOCATION", joinColumns = { 
        @JoinColumn(name = "user_id") }, inverseJoinColumns = { 
        @JoinColumn(name = "locationId") })
private List<FileLocation> fileLocations = new ArrayList<FileLocation>() ;

public YFUser(){

}

public int getUserId() {
    return userId;
}

private void setUserId(int userId) {
    this.userId = userId;
}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public List<FileLocation> getFileLocations() {
    if(fileLocations ==null){
        fileLocations = new ArrayList<FileLocation>();
    }
    return fileLocations;

}

public void setFileLocations(List<FileLocation> fileLocations) {
    this.fileLocations = fileLocations;
}
/*
public void addFileLocation(FileLocation location){
    fileLocations.add(location);
}*/

@Override
public void addProxyInformation(String property, Object proxyInfo) {
    // TODO Auto-generated method stub

}

@Override
public String getDebugString() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public Object getProxyInformation(String property) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public boolean isInitialized(String property) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public void removeProxyInformation(String property) {
    // TODO Auto-generated method stub

}

@Override
public void setInitialized(String property, boolean initialised) {
    // TODO Auto-generated method stub

}

@Override
public Object getValue() {
    // TODO Auto-generated method stub
    return null;
}

}

@Entity
@Table(name = "fileLocationTable")
public class FileLocation implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "locationId", updatable = false, nullable = false)
private int ieId;
@Column (name = "location")
private String location;


public FileLocation(){

}

public int getIeId() {
    return ieId;
}

private void setIeId(int ieId) {
    this.ieId = ieId;
}

public String getLocation() {
    return location;
}

public void setLocation(String location) {
    this.location = location;
}

}

Apr 2, 2010 11:33:12 PM org.hibernate.LazyInitializationException <init>
SEVERE: failed to lazily initialize a collection of role: com.example.client.YFUser.fileLocations, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.client.YFUser.fileLocations, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
at org.hibernate.collection.AbstractPersistentCollection.write(AbstractPersistentCollection.java:205)
at org.hibernate.collection.PersistentBag.add(PersistentBag.java:297)
at com.example.server.TestServiceImpl.saveFileLocation(TestServiceImpl.java:132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at net.sf.gilead.gwt.PersistentRemoteService.processCall(PersistentRemoteService.java:174)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:224)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
Apr 2, 2010 11:33:12 PM net.sf.gilead.core.PersistentBeanManager clonePojo
INFO: Third party instance, not cloned : org.hibernate.LazyInitializationException:     failed to lazily initialize a collection of role: com.example.client.YFUser.fileLocations, no session or session was closed
A: 

Lazy means that the values of the collection are loaded from the database only when they are accessed. If at that time the Session has been closed, the LazyInitializationException is thrown, because the data cannot be fetched.

In your case I'd simply suggest adding an eager fetch type to the association:

@ManyToMany(cascade = CascadeType.ALL, fetchType=FetchType.EAGER)

This will load the fileLocations when the entity is loaded and no lazy loading will be needed.

A common solution is to use OpenSessionInView, but it may not always work with GWT, becaucse the client is remote and the session cannot be opened there.

So you are going to have some problems with lazy initialization. You can search around for related questions, there are a few - this and this for example.

Bozho
cheers dude.. very helpful
molleman
@Bozho, you're correct about the exception but note that eager loading might just mask his problem as: 1. He still needs to sync (merge) this user against a session to have its new fileLocations persisted. 2. The common use-case for Gilead is to have it replace uninitialized proxies with NULL so you won't get such exceptions. I think the OP might be confused a bit about his Gilead implementation as all the ILightEntity methods are from the eclipse auto implementation (i.e. unimplemented).
Ittai
A: 

This exception means that the FileLocations association is not yet loaded and you are trying to access it. There is no session opened, and there is no way to load the association. This is the LazyInitializationException.

Edit: Read Bozho's post for the solution.

Petar Minchev