简体   繁体   中英

org.hibernate.LazyInitializationException associated collection

I have two model classes which are related by many-to-many relationships:

@Entity
@XmlRootElement
@DynamicInsert (value = true)
@DynamicUpdate (value = true)
public class Matchs {

    @Id @GeneratedValue
    private Long matchId;
    private int size;
    private Date begins;
    private Date cutOff;
    private BigDecimal buyIn;

    @ManyToMany
    private List<Users> users;
}

@Entity
@XmlRootElement
@DynamicInsert (value = true)
@DynamicUpdate (value = true)
public class Users {

    @Id
    private String username;
    private String lastName,firstName,password,email;

    private Date dateOfBirth;

    @ManyToMany
    private List<Matchs> matchs;
}

I'm using a DAO to get a Match with all associated Users:

public Matchs findMatchWithUsers(long matchId) 
{
    if (matchId <= 0)
        throw new IllegalArgumentException("Match Id cannot be less than or equal to zero");

    try {
        begin();
        Matchs match = (Matchs) getSession().get(Matchs.class, matchId);

        if (match != null)
            Hibernate.initialize(match.getUsers());

        commit();
        close();
        return match;
    } catch (HibernateException e) {
        rollback();
        close();
        throw e;
    }
}

I then call a Jersey web service:

   @GET
@Path ("getMatch/{matchId}")
@Produces (MediaType.APPLICATION_JSON)
public Response getMatchById  (@PathParam ("matchId")long matchId)
{
    MatchDAO matchDAO = DAO.getInstance(MatchDAO.class);
    Matchs match = matchDAO.findMatchWithUsers(matchId);

    if (match != null)
        return Response.ok()
                       .entity(new GsonBuilder().setPrettyPrinting().create().toJson(match))
                       .build();

    return Response.status(Status.NOT_FOUND).entity("Match was not located").build();
}

But this throws the following exception:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.kyrogaming.models.Users.matchs, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:266)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:95)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
at com.google.gson.Gson.toJson(Gson.java:593)
at com.google.gson.Gson.toJson(Gson.java:572)
at com.google.gson.Gson.toJson(Gson.java:527)
at com.google.gson.Gson.toJson(Gson.java:507)
at com.kyrogaming.services.MatchService.getMatchById(MatchService.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:565)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:479)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:521)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:227)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1031)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:965)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111)
at org.eclipse.jetty.server.Server.handle(Server.java:349)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:449)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:910)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:634)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:76)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:609)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:45)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534)

Where have I gone wrong because I really don't have a clue why the User proxy objects are not initializing.

This is Abstract class is extended by All Hibernate DAO classes and contains methods to interact with hibernate.

public abstract class AbstractHibernate <T>{
private SessionFactory sessionFactory;

private Session session;

@Inject
public void setSessionFactory (SessionFactory sessionFactory)
{
    this.sessionFactory = sessionFactory;
}



protected Session getSession () 
{
    if (sessionFactory == null)
        throw new NullPointerException("SessionFactory null ");
    if (session == null)
    {
        session = sessionFactory.openSession();
        return session; 
    }
    return session;
}


public void begin ()
{
    getSession().beginTransaction();
}



public void commit () throws HibernateException
{
    getSession().getTransaction().commit();
}


public void rollback ()
{
    getSession().getTransaction().rollback();
}


protected void close ()
{
    if (getSession () != null)
    {
        session.close();
        session = null;
    }
}

I assume the code in .entity(new GsonBuilder().setPrettyPrinting().create().toJson(match)) is calling User.getMatchs() but because you have closed your session, it can't load them lazily. You should either load them eagerly or load before closing the session.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM