[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-2477) lazy fetching ManyToOne produces inproper proxies when using single table inheritance strategy

Chris Lowe (JIRA) noreply at atlassian.com
Wed Aug 27 15:16:27 EDT 2008


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2477?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_31004 ] 

Chris Lowe commented on HHH-2477:
---------------------------------

Chris, thanks for the prompt response.

I accept your workarounds are valid for a pure Hibernate environments, but as a pure EJB3 environment this isn't this still an issue? 

Like Sebastian Kirsch comments above, I'm getting this issue with a JOINED inheritance.   Before adding a lazy association my EJBQL was returning a subclass as expected.  After adding the lazy association I now get the root superclass.  This behaviour was not expected.  I've even gone as far specifying my query in terms of the expected subclass, but I still get the root superclass - so how can I even get to my subclass at all?!  What's more,  the lazy associations that I have specified are not even directly against any of the classes in the inheritance structure - they're on the One side of a ManyToOne.  The Many side is on the entities in the inheritance structure, but aren't the Hibernate implementations of the various collections supposed to prevent the need for proxying the parent class?

So with respect to Hibernate being the provider to an EJB3 implementation, is this still an issue?  Or is this something that needs to be taken up elsewhere?

I feel like I'm faced with something that essentially makes essentially makes entity Inheritance and FetchStrategy.LAZY mutually exclusive and that just seems wrong.  There was nothing to hint at this problem in the Hibernate EJB3 docs (or even after scanning through the EJB3 spec for that matter).

Best regards,

Chris.

> lazy fetching ManyToOne produces inproper proxies when using single table inheritance strategy
> ----------------------------------------------------------------------------------------------
>
>                 Key: HHH-2477
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2477
>             Project: Hibernate3
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.2.1
>         Environment: hibernate 3.2.1-GA, postgresql 8.1
>            Reporter: Daniel Nguyen
>         Attachments: bug.zip
>
>   Original Estimate: 1 hour
>  Remaining Estimate: 1 hour
>
> I have entity base class Vehicle and entity class Car which extends Vehicle (using single table inheritance strategy).
> I also have entity class User which have single-ended @ManyToOne relation from User to Vehicle with lazy fetching.
> Now there is a Car instance "c" and User instance "u" with relation to "c". Lazily fetching vehicle from "u" results with proxy object "o" which is instanceof Vehicle but not instanceof Car as expected. So it's impossible cast "o" to Car or at least read any of Car's property from "o".
> This is serious problem when inheritance is extensively used because inproper proxy object remains in cache. To walkaround I'd have to resign with lazy fetching (much performance loss) or manually replace proxy object in cache.
> testing code:
>     SessionFactory sf = null;
>     Session s = null;
>     Transaction tx = null;
>     try
>     {
>       sf = cfg.buildSessionFactory();
>       s = sf.openSession();
>       tx = s.beginTransaction();
>       
>       //create car
>       Car car = new Car();
>       car.setIdVehicle(1);
>       car.setAge(5);
>       s.save(car);
>       
>       //create user of car
>       User user = new User();
>       user.setIdUser(1);
>       user.setVehicle(car);
>       s.save(user);
>       
>       //make sure it is actually added
>       s.flush();
>       // test 1 - works ok, because we loaded vehicle before user
>       s.clear(); //clear cache
>       Vehicle vv = (Vehicle)s.get(Vehicle.class, 1);
>       User uu = (User)s.get(User.class, 1);
>       //we know that user vehicle is actually a Car
>       Car cc = (Car)uu.getVehicle();
>       
>       // test 2 - fails, when using lazy fetching
>       s.clear(); //clear cache
>       User u = (User)s.get(User.class, 1);
>       Vehicle v = u.getVehicle();
>       //we know that user vehicle is actually a Car
>       //so we cast to Car but ClassCastException is raised!!!
>       Car c = (Car)v;
>       //let's check what's actual class of v
>       System.out.println(v.getClass().getName());
>       System.out.println(v.getClass().getSuperclass().getName());
>       //result:
>       //  test.hibernate.Vehicle$$EnhancerByCGLIB$$12ce1883
>       //  test.hibernate.Vehicle
>       //but I expected:
>       //  test.hibernate.Car$$EnhancerByCGLIB$$xxxxx
>       //  test.hibernate.Car
>     }
>     finally
>     {
>       if (tx!=null)
>         tx.rollback();
>       if (s!=null)
>         s.close();
>       if (sf!=null)
>         sf.close();
>     }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list