[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5001?page=c...
]
Matt Accola commented on HHH-5001:
----------------------------------
Well I found a much better description of the problem on the Hibernate Wiki,
https://www.hibernate.org/280.html. It appears this is the "dreaded proxy
problem". Seeing as this is apparently a well-known issue I would suspect there is
not going to be any action taken on this JIRA issue.
I do think the Hibernate Reference Guide could be a little more forthcoming on the matter.
Especially section 19.1.3. If you read that section you would think that simply
switching to proxy interfaces would solve all your problems. Unfortunately, the section
fails to mention that even the proposed interface proxy approach has issues. The
interface proxy approach makes instanceof operations unreliable and allows objects to be
downcast to incorrect subinterfaces. In addition, mixing a lazy superclass and a non-lazy
subclass in the same hierarchy can cause attempts to downcast a proxy to the non-lazy
subinterface to fail.
Polymorphism not always supported for queries and associations when
using interface proxies
-------------------------------------------------------------------------------------------
Key: HHH-5001
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5001
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.3.2
Environment: Oracle 10
Reporter: Matt Accola
Attachments: HibernateInheritance.zip, SampleTestResults.zip
On our project we have started using Hibernate inheritance widely and we are facing
issues when we map entities in the inheritance hierarchies as lazy=true at the class level
and when we map polymorphic, single-ended associations (many-to-one and one-to-one).
Originally we were relying on the default Hibernate-generated proxies. We were loading
objects polymorphically using iterate or load. In the HQL statement or the parameter to
the load method we would specify the superclass type. Also, for polymorphic, single-ended
associations we were declaring the property to be of the superclass type. The end result
was when we try to downcast an object which should be a subclass into its subclass we get
a ClassCastException.
This behavior is well documented in section "19.1.3. Single-ended association
proxies" of the Hibernate documentation. In that section it describes a solution
using proxy interfaces. So, we created a parallel hierarchy of proxy interfaces for our
inheritance hierarchy. There are still issues with this approach. I will summarize the
most serious issues we have documented so far:
1. If the superclass is mapped as lazy=true and the subclass is mapped as lazy=true the
subclass objects will not exhibit proper behavior when loaded polymorphically with iterate
or load. All possible interfaces are proxied, both correct interfaces and incorrect
interfaces. This makes instanceof operations unreliable. The ClassCastException is
simply deferred to the time when a method from the wrong subclass interface is invoked.
2. If the superclass is mapped as lazy=true and the subclass is mapped as lazy=true the
subclass objects will not exhibit proper behavior when loaded via single-ended
associations (many-to-one or one-to-one). Same behavior as bullet point #1.
3. If the superclass is mapped as lazy=true and the subclass is mapped as lazy=false the
subclass objects will not exhibit proper behavior when loaded polymorphically with iterate
or load. The object cannot be downcast to its subclass.
Changing all class-level mappings for all classes in the inheritance hierarchy to
lazy=false AND changing all single-ended associations to eager fetch seems to resolve the
issue. However, we do not desire to eager fetch all these objects.
Another possible "fix" is to always use the exact subclass when loading the
objects (in the HQL query or as a parameter to the load) but this eliminates polymorphism
completely. Also, it would be impossible to map polymorphic associations...all
associations would need to declare a specific subclass.
I have uploaded an entire Eclipse project which demonstrates the issues with the proxy
interface approach. To run the tests in the project you need to do the following steps:
1. Import the project into Eclipse
2. Setup your DB connection properties in src/main/resources/local.properties
3. Run the script in DB.txt against your target schema
On a final note I spent a fair amount of time going through the JIRA issues that
mentioned polymorphism. This topic seems to have been touched several times and rejected
quickly with a brief not to "read the documentation". I assure you I have read
the documentation many times searching for clues on how to accomplish this and I am at a
dead end. If there is a simple way to do this please take the time to provide a few
sentences to lead us in the right direction. Your help is appreciated!
Related JIRA issues?
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2927
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2921
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1347
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1288
http://opensource.atlassian.com/projects/hibernate/browse/HHH-4511
http://opensource.atlassian.com/projects/hibernate/browse/HB-382
--
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....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira