-
Notifications
You must be signed in to change notification settings - Fork 227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HibernateProxyConverter - wrong serialization in case of abstract class #73
Comments
Well, the issue is not with HibernateProxyConverter, but with HibernateMapper. It contains this code:
This is WRONG. If JPA entity inheritance is being used, clazz.getSuperclass() might return abstract class (the actual type of field, NOT of the object behind the proxy). The CORRECT way to get the class of object behind the proxy is:
or
But here we hit XStream internal design issue: Mappers do not have access to objects being serialized, only to their classes. Any ideas? |
Beware: The Hibernate module was completely contributed by other users, personally I never did something with it. You're last comment is right: You do not have access to the real object in the mapper. Therefore I'd implement something along your first solution. The class attribute will overwrite any other type here. |
Well I have tried to add following line to HibernateProxyConverter:
but then as a result I get "Duplicated attribute error". It seems that sometimes parent converter (AbstractReflectionConverter) adds this attribute itself. Question: are there any means to ask HierarchicalStreamWriter to overwrite the attribute? |
Well, normally the task of a converter is to represent the current object in XML. This principle is violated by the HibernateProxyConverter on purpose to remove any trace of the proxy object from the XML representation. Normally the marshal method should be implemented like: public void marshal(final Object object, final HierarchicalStreamWriter writer, final MarshallingContext context) {
HibernateProxy hibernateProxy = (HibernateProxy) object;
final Object item = hibernateProxy.getHibernateLazyInitializer().getImplementation();
writer.startNode("hibernate-proxy");
writer.addAttribute("class", Hibernate.getClass(hibernateProxy).getName());
context.convertAnother(item);
writer.endNode();
} Since the converter does not represent its own object (on purpose), you get this problem with the double class attribute. The so-called parent converter simply detects that the declared type of the field does not match the real type of the object and writes therefore the proper class attribute (since it has to keep all information to recreate the elements ... normally). I'd expect that you get this always when you've declared the member to be of type AbstractEntity. Is that the case? |
I cannot go further without more info or a little test case. |
Hibernate allows to use entity inheritance, thus this code is valid:
private AbstractEntity myEntity = new ChildEntity();
During runtime object of ChildEntity gets proxied (by HibernateProxy). But HibernateProxyConverter currently outputs just this:
Since AbstractEntity is abstract class upon deserialization I'm getting:
Obviously AbstractReflectionConverter doesn't know what real class must be used and just tries to use the type of field "myEntity".
I have fixed this by modifying HibernateProxyConverter this way:
That is, add the attribute "class" with the value of real object class. Now serialization result is:
and deserialization works OK.
Could you please correct this issue with HibernateProxyConverter?
The text was updated successfully, but these errors were encountered: