XStream and domain class inheritance question

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

XStream and domain class inheritance question

thomas fuller
Hi,

I seem to have run into a problem with unmarshalling a domain class using XStream and I'm not sure what I'm missing here. Let me show you what the class looks like as this may help:

(I'll do my best to keep this brief)

@XStreamAlias(WB_SOURCE)
public class Source extends IdValuePair {

    @XStreamAlias(WB_NAME)
    @XStreamConverter (ValueAsStringConverter.class)
    private String name = null;

...
}

public class IdValuePair extends IdentityObject {

    @XStreamConverter(ValueAsStringConverter.class)
    private String value = null;

...
}

public class IdentityObject extends DefaultObject
    implements IdentitySpecification<String> {

    @XStreamAlias(ID)
    @XStreamAsAttribute
    private String id = null;

...
}

The problem I'm facing is that the name is unmarshalled properly, however the value and id are not. If I add a custom source converter, I can achieve this however I have the feeling that this should not be necessary as XStream should proces the annotations present on parent classes (and there appears to be a bug that was fixed several years ago that addressed the problem I'm talking about now).

Any thoughts on this would be helpful.

Thanks,

Tom
Reply | Threaded
Open this post in threaded view
|

Re: XStream and domain class inheritance question

Jörg Schaible-2
Hi Tom,

Thomas Fuller wrote:

> Hi,
>
> I seem to have run into a problem with unmarshalling a domain class using
> XStream and I'm not sure what I'm missing here. Let me show you what the
> class looks like as this may help:
>
> (I'll do my best to keep this brief)
>
> @XStreamAlias(WB_SOURCE)
> public class Source extends IdValuePair {
>
>     @XStreamAlias(WB_NAME)
>     @XStreamConverter (ValueAsStringConverter.class)
>     private String name = null;
>
> ...
> }
>
> public class IdValuePair extends IdentityObject {
>
>     @XStreamConverter(ValueAsStringConverter.class)
>     private String value = null;
>
> ...
> }
>
> public class IdentityObject extends DefaultObject
>     implements IdentitySpecification<String> {
>
>     @XStreamAlias(ID)
>     @XStreamAsAttribute
>     private String id = null;
>
> ...
> }
>
> The problem I'm facing is that the name is unmarshalled properly, however
> the value and id are not. If I add a custom source converter, I can
> achieve this however I have the feeling that this should not be necessary
> as XStream should proces the annotations present on parent classes (and
> there appears to be a bug that was fixed several years ago that addressed
> the problem I'm talking about now).
>
> Any thoughts on this would be helpful.

actually I have not enough information to say something useful. What version
of XStream you're using? How do you initialize the XStream? How does the
processes XML look like?

Best would be to write a little unit test with a minimal set of classes
(just like above) that demonstrates the problem.

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: XStream and domain class inheritance question

thomas fuller
Hi Jörg

There is an integration test in the attached file which demonstrates the problem I'm facing -- it is located here:

wb-client-core-it\src\test\java\com\coherentlogic\wb\client\core\builders\QueryBuilderTest.java

The specific tests worth looking at are listed below -- the problem is that the value property in the IdValuePair class is never set. I've done enough research on this and think I'm probably missing something.

wb-client-core\src\main\java\com\coherentlogic\wb\client\core\domain\Topic.java (etc.)
wb-client-core\src\main\java\com\coherentlogic\wb\client\core\domain\IdValuePair.java

These are the tests -- of particular interest is each class on the right, which extends from IdValuePair.

testIncomeLevels (IncomeLevel -- test on line # 308)
testLendingTypes (LendingType # 448)
testTopics (Topic # 470)

Thanks for your help,

Tom


On Sat, May 11, 2013 at 7:04 AM, Jörg Schaible <[hidden email]> wrote:
Hi Tom,

Thomas Fuller wrote:

> Hi,
>
> I seem to have run into a problem with unmarshalling a domain class using
> XStream and I'm not sure what I'm missing here. Let me show you what the
> class looks like as this may help:
>
> (I'll do my best to keep this brief)
>
> @XStreamAlias(WB_SOURCE)
> public class Source extends IdValuePair {
>
>     @XStreamAlias(WB_NAME)
>     @XStreamConverter (ValueAsStringConverter.class)
>     private String name = null;
>
> ...
> }
>
> public class IdValuePair extends IdentityObject {
>
>     @XStreamConverter(ValueAsStringConverter.class)
>     private String value = null;
>
> ...
> }
>
> public class IdentityObject extends DefaultObject
>     implements IdentitySpecification<String> {
>
>     @XStreamAlias(ID)
>     @XStreamAsAttribute
>     private String id = null;
>
> ...
> }
>
> The problem I'm facing is that the name is unmarshalled properly, however
> the value and id are not. If I add a custom source converter, I can
> achieve this however I have the feeling that this should not be necessary
> as XStream should proces the annotations present on parent classes (and
> there appears to be a bug that was fixed several years ago that addressed
> the problem I'm talking about now).
>
> Any thoughts on this would be helpful.

actually I have not enough information to say something useful. What version
of XStream you're using? How do you initialize the XStream? How does the
processes XML look like?

Best would be to write a little unit test with a minimal set of classes
(just like above) that demonstrates the problem.

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

wbclient.zip (118K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: XStream and domain class inheritance question

Jörg Schaible-2
Hi Thomas,

Thomas Fuller wrote:

> Hi Jörg
>
> There is an integration test in the attached file which demonstrates the
> problem I'm facing -- it is located here:
>
> wb-client-core-
it\src\test\java\com\coherentlogic\wb\client\core\builders\*

> QueryBuilderTest.java*
>
> The specific tests worth looking at are listed below -- the problem is
> that the value property in the IdValuePair class is never set. I've done
> enough research on this and think I'm probably missing something.
>
> wb-client-core\src\main\java\com\coherentlogic\wb\client\core\domain\*
> Topic.java* (etc.)
> wb-client-core\src\main\java\com\coherentlogic\wb\client\core\domain\*
> IdValuePair.java*
>
> These are the tests -- of particular interest is each class on the right,
> which extends from IdValuePair.
>
> testIncomeLevels (IncomeLevel -- test on line # 308)
> testLendingTypes (LendingType # 448)
> testTopics (Topic # 470)
>
> Thanks for your help,

Sorry, but this is not the way it works.

> On Sat, May 11, 2013 at 7:04 AM, Jörg Schaible
> <[hidden email]>wrote:

[snip]

>> Best would be to write a little unit test with a minimal set of classes
>> (just like above) that demonstrates the problem.

You've send me now a fill blown application with several modules based on
Spring and Groovy integration. Actually to demonstrate a problem with
marshalling from Java object to XML and back, you will not need any of those
stuff.

See, this is my unpaid spare time, it is 1:30am and I already spent now some
time to look at some classes, but that's it. You will have to spent *your*
time to strip your code down. I am quite sure, that you can create a unit
test with ~3 classes of your domain model (i.e. what gets marshalled) and
and setup in the test an XStream instance that is comparable to the one
you're using in your project and that demonstrates the problem with the XML
- no Spring or Groovy or something else required.

Be sure, that I will really try to help you then, but please value my time
as high a yours.

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Re: XStream and domain class inheritance question

thomas fuller
Hi Jörg,

Apologies for any inconvenience. Please see the attached zip file -- specifically src/test/Main.java. The is severely cut down and includes everything needed to reproduce the problem.

The unit test is a simple if/then in the main method:

if (!"High income".equals(value)) // This will fail.
        throw new RuntimeException ("Failed: the value is wrong: " + value);

I've tried getting this to work several ways and don't see why the value is not being set.

FYI: I've had to leave out the xstream-1.4.4.jar from the lib folder as the mail server rejected my message due to it exceeding the size limit -- all other dependencies are included though.

Thanks again,

Tom


On Wed, May 15, 2013 at 7:45 PM, Jörg Schaible <[hidden email]> wrote:
Hi Thomas,

Thomas Fuller wrote:

> Hi Jörg
>
> There is an integration test in the attached file which demonstrates the
> problem I'm facing -- it is located here:
>
> wb-client-core-
it\src\test\java\com\coherentlogic\wb\client\core\builders\*
> QueryBuilderTest.java*
>
> The specific tests worth looking at are listed below -- the problem is
> that the value property in the IdValuePair class is never set. I've done
> enough research on this and think I'm probably missing something.
>
> wb-client-core\src\main\java\com\coherentlogic\wb\client\core\domain\*
> Topic.java* (etc.)
> wb-client-core\src\main\java\com\coherentlogic\wb\client\core\domain\*
> IdValuePair.java*
>
> These are the tests -- of particular interest is each class on the right,
> which extends from IdValuePair.
>
> testIncomeLevels (IncomeLevel -- test on line # 308)
> testLendingTypes (LendingType # 448)
> testTopics (Topic # 470)
>
> Thanks for your help,

Sorry, but this is not the way it works.

> On Sat, May 11, 2013 at 7:04 AM, Jörg Schaible
> <[hidden email]>wrote:

[snip]

>> Best would be to write a little unit test with a minimal set of classes
>> (just like above) that demonstrates the problem.

You've send me now a fill blown application with several modules based on
Spring and Groovy integration. Actually to demonstrate a problem with
marshalling from Java object to XML and back, you will not need any of those
stuff.

See, this is my unpaid spare time, it is 1:30am and I already spent now some
time to look at some classes, but that's it. You will have to spent *your*
time to strip your code down. I am quite sure, that you can create a unit
test with ~3 classes of your domain model (i.e. what gets marshalled) and
and setup in the test an XStream instance that is comparable to the one
you're using in your project and that demonstrates the problem with the XML
- no Spring or Groovy or something else required.

Be sure, that I will really try to help you then, but please value my time
as high a yours.

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

problem.zip (58K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: XStream and domain class inheritance question

Jörg Schaible-2
Hi Thomas,

Thomas Fuller wrote:

> Hi Jörg,
>
> Apologies for any inconvenience. Please see the attached zip file --
> specifically src/test/Main.java. The is severely cut down and includes
> everything needed to reproduce the problem.
>
> The unit test is a simple if/then in the main method:
>
> if (!"High income".equals(value)) // This will fail.
>         throw new RuntimeException ("Failed: the value is wrong: " +
>         value);
>
> I've tried getting this to work several ways and don't see why the value
> is not being set.

Well, if I create a IncomesLevel with one IncomeLevel of id 'HIC' and value
"High Income" manually and marshal that to XML, I get:

 ==================== %< ========================
 <wb:IncomeLevels>
   <wb:incomeLevel id="HIC">
     <value>High income</value>
   </wb:incomeLevel>
 </wb:IncomeLevels>
 ==================== %< ========================

This should make it immediately obvious, why the value of your deserialized
IncomeLevel instances is null.

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: XStream and domain class inheritance question

thomas fuller
Hi Jörg,

Re "This should make it immediately obvious, why the value of your deserialized IncomeLevel instances is null."

Maybe to you but I'm still missing it. Note that the deserialized IncomeLevel instances is not actually null. The class is created, the id is set correctly -- it's the value which is null.

If I move the converter and the value property to the IncomeLevel and likewise remove the converter and value property from the IdValuePair, then the XML that is serialized appears to be correct (I've pasted the classes below) -- however this is not where I want this to be.

Here's the XML that is generated after the change below:

<wb:IncomeLevels>
  <wb:incomeLevel id="foo">bar</wb:incomeLevel>
</wb:IncomeLevels>

So, what am I not seeing?

Tom

@XStreamAlias(DefaultObject.WB_INCOME_LEVEL)
@XStreamConverter(value=ToAttributedValueConverter.class, strings={"value"})
public class IncomeLevel extends IdValuePair {

    private static final long serialVersionUID = -8487721255922835678L;

    private String value = null;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

public class IdValuePair extends IdentityObject {

    private static final long serialVersionUID = -5821168050440557783L;

}


On Thu, May 16, 2013 at 2:17 PM, Jörg Schaible <[hidden email]> wrote:
Hi Thomas,

Thomas Fuller wrote:

> Hi Jörg,
>
> Apologies for any inconvenience. Please see the attached zip file --
> specifically src/test/Main.java. The is severely cut down and includes
> everything needed to reproduce the problem.
>
> The unit test is a simple if/then in the main method:
>
> if (!"High income".equals(value)) // This will fail.
>         throw new RuntimeException ("Failed: the value is wrong: " +
>         value);
>
> I've tried getting this to work several ways and don't see why the value
> is not being set.

Well, if I create a IncomesLevel with one IncomeLevel of id 'HIC' and value
"High Income" manually and marshal that to XML, I get:

 ==================== %< ========================
 <wb:IncomeLevels>
   <wb:incomeLevel id="HIC">
     <value>High income</value>
   </wb:incomeLevel>
 </wb:IncomeLevels>
 ==================== %< ========================

This should make it immediately obvious, why the value of your deserialized
IncomeLevel instances is null.

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: Re: XStream and domain class inheritance question

Jörg Schaible-2
Hi Thomas,

Thomas Fuller wrote:

> Hi Jörg,
>
> Re "This should make it immediately obvious, why the value of your
> deserialized IncomeLevel instances is null."
>
> Maybe to you but I'm still missing it. Note that the deserialized
> IncomeLevel instances is not actually null. The class is created, the id
> is set correctly -- it's the value which is null.

For sure, because in your XML the wb:incomeLevel does not have an inner
element with the tag "value". That's how you have configured the XStream --
clearly visible when you create the XML from the objects. That XML element
is not optional, it is expected. Any text of the eb:incomeLevel element is
unexpected and therefore simply ignored.

> If I move the converter and the value property to the IncomeLevel and
> likewise remove the converter and value property from the IdValuePair,
> then the XML that is serialized appears to be correct (I've pasted the
> classes below) -- however this is not where I want this to be.

This is your problem -- you do *not* have a choice where you define the
converter. Each instance of the ToAttributedValueConverter will handle only
one class and that is exactly the one it was registered for. However, you do
not have to move the value property:

================== %< =================
@XStreamConverter(value=ToAttributedValueConverter.class, strings={"value"},
types={IdValuePair.class})
public class IncomeLevel extends IdValuePair {
 // ...
}
================== %< =================

For more convenience, simply derive your own converter:

================== %< =================
public class ValuedConverter extends ToAttributedValueConverter {
  public ValuedConverter(final Class type, final Mapper mapper, final
ReflectionProvider reflectionProvider, final ConverterLookup lookup) {
    super(type, mapper, reflectionProvider, lookup, "value",
IdValuePair.class);
  }
}

@XStreamConverter(ValuedConverter)
public class IncomeLevel extends IdValuePair {
 // ...
}
================== %< =================

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: Re: XStream and domain class inheritance question

thomas fuller
Hi Jörg,

I used the types=... solution and that works.

Appreciate your help,

Tom


On Thu, May 16, 2013 at 7:05 PM, Jörg Schaible <[hidden email]> wrote:
Hi Thomas,

Thomas Fuller wrote:

> Hi Jörg,
>
> Re "This should make it immediately obvious, why the value of your
> deserialized IncomeLevel instances is null."
>
> Maybe to you but I'm still missing it. Note that the deserialized
> IncomeLevel instances is not actually null. The class is created, the id
> is set correctly -- it's the value which is null.

For sure, because in your XML the wb:incomeLevel does not have an inner
element with the tag "value". That's how you have configured the XStream --
clearly visible when you create the XML from the objects. That XML element
is not optional, it is expected. Any text of the eb:incomeLevel element is
unexpected and therefore simply ignored.

> If I move the converter and the value property to the IncomeLevel and
> likewise remove the converter and value property from the IdValuePair,
> then the XML that is serialized appears to be correct (I've pasted the
> classes below) -- however this is not where I want this to be.

This is your problem -- you do *not* have a choice where you define the
converter. Each instance of the ToAttributedValueConverter will handle only
one class and that is exactly the one it was registered for. However, you do
not have to move the value property:

================== %< =================
@XStreamConverter(value=ToAttributedValueConverter.class, strings={"value"},
types={IdValuePair.class})
public class IncomeLevel extends IdValuePair {
 // ...
}
================== %< =================

For more convenience, simply derive your own converter:

================== %< =================
public class ValuedConverter extends ToAttributedValueConverter {
  public ValuedConverter(final Class type, final Mapper mapper, final
ReflectionProvider reflectionProvider, final ConverterLookup lookup) {
    super(type, mapper, reflectionProvider, lookup, "value",
IdValuePair.class);
  }
}

@XStreamConverter(ValuedConverter)
public class IncomeLevel extends IdValuePair {
 // ...
}
================== %< =================

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email