A robust starter web application to ease Java webapp development.

Home | Tutorials | Demos | Issues

Lazy Exception again. WTF?

View: New views
6 Messages — Rating Filter:   Alert me  

Lazy Exception again. WTF?

by syg6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I posted a similar message a while back. I only got one response. I thought I had fixed my problem by eagerly loading my Object's Collections when needed. But no, it's broke again.

In summary, I am getting the famous 'could not initialize proxy - no Session' error when trying to display a list of Inspections. It started appearing after I made all of my Collections LAZY to make loading easier on the DB.

The Object in question is Inspection and it has 2 Collections: infractions and residuos. NEITHER of these Collections are referenced in the list page so I should not be getting a Lazy Exception. In fact, this particular Lazy Exception is a mystery to me. It's not the typical 'Unable to load Collection' error that I would except if, for example, I tried to reference an Object's Collection if that Collection is lazily loaded.

In fact, the error does not occur in the page at all but rather in the Manager! I changed the Manager's code so it would eagerly load my two Collections. This seemed to work, I stopped getting the Lazy Exception error for a while. But it stopped working. This is the code:

public List<Inspection> findByStatus(Long idStatus)
{
  List<Inspection> inspections = getHibernateTemplate().find("from Inspection where inspeccionStatus.id = ?", idStatus);
  ArrayList<Inspection> eagerInspections = new ArrayList<Inspection>();
 
  for (int i=0; i<inspections.size(); i++)
  {
    Inspection inspection = inspections.get(i);
    inspection = getEager(inspection.getId());
    eagerInspections.add(inspection);
  }
 
  return eagerInspections;
}

public Inspeccion getEager(Long id)
{
    Inspection i = get(id);
    Hibernate.initialize(i.getInfractions());
    Hibernate.initialize(i.getResidues());
    return i;
}

As I said, this code seemed to do the trick. But all of a sudden it's broke again. I have no idea what the problem is. It seems the problem is NOT (and never has been) the Collections. Here is part of the stack trace. Is something wrong my my hashCode() methods?

2008-07-09 10:44:45.694::WARN:  Nested in org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.LazyInitializationException: could not initialize proxy - no Session:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
        at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
        at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
        at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
        at com.myco.myapp.model.InspectionPacket$$EnhancerByCGLIB$$fa7dc626.hashCode(<generated>)
        at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:856)
        at com.myco.myapp.model.Request.hashCode(Request.java:418)
        at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:856)
        at com.myco.myapp.model.Inspection.hashCode(Inspeccion.java:419)


When I first changed from Eager to Lazy, many of my Objects broke because I had those Objects' Collections in the hashCode() and toString() methods. But not anymore. My Inspection Object DOES have an InspectionPacket Object and a Request Object but the relation is ManyToOne and I understand that Hibernate eagerly loads ManyToOne relationships. These two Objects' hashCode() methods are fine.

I really have no idea what is going on. Can someone give me a clue?

Thanks,
Bob

Re: Lazy Exception again. WTF?

by syg6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sure enough it was a hashCode issue.

In the stack trace I had the following line:

com.myco.myapp.model.Request.hashCode(Request.java:418)

When I went to my hashCode method it looked pretty normal:

return new HashCodeBuilder().append(code).append(type) ...

The offending line was:

append(inspectionPacket)

What could be wrong with InspectionPacket? I didn't know. I took it out of Request's hashCode() method and everything worked. Hmmm ...

I went to take a look at Request and sure enough my ManyToOne mapping for InspectionPacket was bad:

@ManyToOne(fetch = FetchType.LAZY)

I have no idea why I made it Lazy. It's the only Association in my entire application mapped that way. All of my Associations (ManyToOne) are EAGER and all of my Collections (OneToMany or ManyToMany) are LAZY.

Lesson learned. You get a Lazy Exception saying 'such-and-such a Collection could not be loaded' when it's a problem with a lazily-loaded Collection. Obviously. But when it's an Association, instead of saying 'Association could not be loaded' it says 'no proxy'. Ok then.

I hope this helps someone, somewhere. It certainly cleared up a mystery for me!

Bob
               

, just a bunch of


syg6 wrote:
I posted a similar message a while back. I only got one response. I thought I had fixed my problem by eagerly loading my Object's Collections when needed. But no, it's broke again.

In summary, I am getting the famous 'could not initialize proxy - no Session' error when trying to display a list of Inspections. It started appearing after I made all of my Collections LAZY to make loading easier on the DB.

The Object in question is Inspection and it has 2 Collections: infractions and residuos. NEITHER of these Collections are referenced in the list page so I should not be getting a Lazy Exception. In fact, this particular Lazy Exception is a mystery to me. It's not the typical 'Unable to load Collection' error that I would except if, for example, I tried to reference an Object's Collection if that Collection is lazily loaded.

In fact, the error does not occur in the page at all but rather in the Manager! I changed the Manager's code so it would eagerly load my two Collections. This seemed to work, I stopped getting the Lazy Exception error for a while. But it stopped working. This is the code:

public List<Inspection> findByStatus(Long idStatus)
{
  List<Inspection> inspections = getHibernateTemplate().find("from Inspection where inspeccionStatus.id = ?", idStatus);
  ArrayList<Inspection> eagerInspections = new ArrayList<Inspection>();
 
  for (int i=0; i<inspections.size(); i++)
  {
    Inspection inspection = inspections.get(i);
    inspection = getEager(inspection.getId());
    eagerInspections.add(inspection);
  }
 
  return eagerInspections;
}

public Inspeccion getEager(Long id)
{
    Inspection i = get(id);
    Hibernate.initialize(i.getInfractions());
    Hibernate.initialize(i.getResidues());
    return i;
}

As I said, this code seemed to do the trick. But all of a sudden it's broke again. I have no idea what the problem is. It seems the problem is NOT (and never has been) the Collections. Here is part of the stack trace. Is something wrong my my hashCode() methods?

2008-07-09 10:44:45.694::WARN:  Nested in org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.LazyInitializationException: could not initialize proxy - no Session:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
        at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
        at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
        at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
        at com.myco.myapp.model.InspectionPacket$$EnhancerByCGLIB$$fa7dc626.hashCode(<generated>)
        at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:856)
        at com.myco.myapp.model.Request.hashCode(Request.java:418)

        at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:856)
        at com.myco.myapp.model.Inspection.hashCode(Inspeccion.java:419)


When I first changed from Eager to Lazy, many of my Objects broke because I had those Objects' Collections in the hashCode() and toString() methods. But not anymore. My Inspection Object DOES have an InspectionPacket Object and a Request Object but the relation is ManyToOne and I understand that Hibernate eagerly loads ManyToOne relationships. These two Objects' hashCode() methods are fine.

I really have no idea what is going on. Can someone give me a clue?

Thanks,
Bob

Re: Lazy Exception again. WTF?

by Alex Coles :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jul 9, 2008, at 11:53 AM, syg6 wrote:

>
> Sure enough it was a hashCode issue.
>
> In the stack trace I had the following line:
>
> com.myco.myapp.model.Request.hashCode(Request.java:418)
>
> When I went to my hashCode method it looked pretty normal:
>
> return new HashCodeBuilder().append(code).append(type) ...
>
> The offending line was:
>
> append(inspectionPacket)
>
> What could be wrong with InspectionPacket? I didn't know. I took it  
> out of
> Request's hashCode() method and everything worked. Hmmm ...
>
> I went to take a look at Request and sure enough my ManyToOne  
> mapping for
> InspectionPacket was bad:
>
> @ManyToOne(fetch = FetchType.LAZY)
>
> I have no idea why I made it Lazy. It's the only Association in my  
> entire
> application mapped that way. All of my Associations (ManyToOne) are  
> EAGER
> and all of my Collections (OneToMany or ManyToMany) are LAZY.
>
> Lesson learned. You get a Lazy Exception saying 'such-and-such a  
> Collection
> could not be loaded' when it's a problem with a lazily-loaded  
> Collection.
> Obviously. But when it's an Association, instead of saying  
> 'Association
> could not be loaded' it says 'no proxy'. Ok then.
>
> I hope this helps someone, somewhere. It certainly cleared up a  
> mystery for
> me!
>
> Bob


I have hit 2 issues before where I've included Collections in my  
hashCode() and equals() - both Lazy Exceptions and NPE's.

I only include boxed primitive (String) properties + @Embedded  
properties when I write my hashCode() and equals().
Of course, if you have a property that you know should be unique - a  
natural key - in addition to your surrogate key, you can just use that  
one property as the basis of your hashCode() and equals() methods...

Getting hashCode() and equals() is really important (and not as easy  
as it seems!).. I've had a bunch of really weird errors bubble up  
further up the stack where I've gotten it wrong. I'd appreciate  
anyones thoughts on how to test those methods.

Alex


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...


Re: Lazy Exception again. WTF?

by syg6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hmmm ...

Alexander Coles wrote:
I only include boxed primitive (String) properties + @Embedded  
properties when I write my hashCode() and equals().
Of course, if you have a property that you know should be unique - a  
natural key - in addition to your surrogate key, you can just use that  
one property as the basis of your hashCode() and equals() methods...
I thought about getting rid of all the 'junk' that winds up in your hashCode() and toString() methods. I thought about only using primatives. But wouldn't this (possibly) cause identification errors? The Hibernate docs say NOT to use the database id. So if you have an Object with a bunch of int and String fields, as well as other user-defined fields, like this:

class ParentObject
{
  int field1;
  int field2;
  String field3;
  String field4;
  MyObject1 field4;
  MyObject2 field5;
}

Shouldn't you also stick 'MyObject1' and 'MyObject2' in the hashCode() and toString() methods, just to be safe (ie. make it easier for Hibernate to uniquely identify the object by giving it more fields as criteria)?

I don't use Collections in hashCode() and toString(). Too many problems.

Thanks for the reply!

Bob

Re: Lazy Exception again. WTF?

by Alex Coles :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jul 9, 2008, at 12:19 PM, syg6 wrote:

>
> Hmmm ...
>
> Shouldn't you also stick 'MyObject1' and 'MyObject2' in the  
> hashCode() and
> toString() methods, just to be safe (ie. make it easier for  
> Hibernate to
> uniquely identify the object by giving it more fields as criteria)?
>

Yes, but - what are MyObject1 and MyObject2? Unless I'm forgetting  
something, they'll either be @Transient, @Embedded properties or  
custom User Types?

> I don't use Collections in hashCode() and toString(). Too many  
> problems.

Agreed. I don't think its best practise either.

> Thanks for the reply!
>
> Bob


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...


Re: Lazy Exception again. WTF?

by John Kwon :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I've always thought of hashCode and equals (even back in the smalltalk days) as being keys in the relational sense.

If I have an object that's mapping to a table, whatever is being identified as a key using annotations are the only attributes I use in hashCode and equals.

I don't include any non-key attributes.
LightInTheBox - Buy quality products at wholesale price