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

Tun Schlechter (JIRA) noreply at atlassian.com
Mon Mar 31 03:27:33 EDT 2008


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

Tun Schlechter commented on HHH-2477:
-------------------------------------

This is a very annoying BUG and unfortunately, the above descriptions and motivations suggest that it will not be easy to fix it. If you are not too much annoyed by the limitations of Toplink-essentials, you might try it as a persistence provider, it does not have this bug.

Otherwise, you can add a persistent attribute to your classes that takes the classname upon construction. Later you will evaluate this attribute, instead of using the instanceof operator. With JOINED Inheritance, the solution has the added benefit, that you can determine the classname manually in your DB while looking at the table of the highest superclass.

> 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