I initially posted this a day or so ago, I assume that it got overlooked as a
result of my posting it as a reply to something else, so it wasn't evident
that I was asking for help. Sorry I didn't get this right the first time.

The problem I'm having is that using the location attribute in the mapping
file causes the wrong setter method to be called during unmarshalling when I
have nested elements that share the same name. It might also have something to
do with the fact that location is used for one binding and not for the
following one. Or conceivably I might not know what I'm doing. Anyway, I get
the same behavior whether I use namespaces or not (the included example does not).

I got this using Castor 0.9.5.2 with jdk1.3.1 on Windows 2000. All the details
needed to reproduce this behavior are included below, I tried to make it as
short as possible.

thank you,
Newton


the instance document to unmarshal:

<?xml version="1.0" encoding="UTF-8"?>
<TransactionSet>
      <Transaction>
            <User>
                  <UserID>user id</UserID>
<!-- comment out the next line and this document unmarshals with no errors
-->
                  <Remarks>remark for user</Remarks>
            </User>
            <Remarks>remark for transaction</Remarks>
      </Transaction>
<!--  <Remarks>remark for transactionset</Remarks> -->
</TransactionSet>

the mapping xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapping SYSTEM "mapping.dtd">
<mapping>

  <class name="com.foo.persistent.TransactionSet">
    <map-to xml="TransactionSet"/>
    <field name="transactions" type="com.foo.persistent.Transaction"
collection="set"/>
    <field name="remark" type="string" set-method="setRemark"
get-method="getRemark">
      <bind-xml name="Remarks" node="element"/>
    </field>
  </class>

  <class name="com.foo.persistent.Transaction">
    <map-to xml="Transaction"/>
    <field name="userId" type="string" set-method="setUserId"
get-method="getUserId">
        <bind-xml name="UserID" node="element" location="User"/>
    </field>

    <field name="remark" type="string" set-method="setRemark"
get-method="getRemark">
      <bind-xml name="Remarks" node="element"/>
    </field>
  </class>

</mapping>

the stack trace:

this is the exception that is normally seen:

org.xml.sax.SAXException: unable to add 'Remarks' to <TransactionSet> due
to the following exception:
>>>--- Begin Exception ---<<<
java.lang.IllegalArgumentException: Type conversion error: could not set
value of remark(java.lang.String) with value of type java.lang.String
      at
org.exolab.castor.mapping.loader.FieldHandlerImpl.setValue(FieldHandlerImpl.java
:474)
      at
org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:852)
      at
org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:918)
      at
org.apache.xerces.parsers.SAXParser.endElement(SAXParser.java:1403)
      at
org.apache.xerces.validators.common.XMLValidator.callEndElement(XMLValidator.jav
a:1436)
      at
org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher.dispatch(XMLDoc
umentScanner.java:1205)
      at
org.apache.xerces.framework.XMLDocumentScanner.parseSome(XMLDocumentScanner.java
:381)
      at org.apache.xerces.framework.XMLParser.parse(XMLParser.java:1035)
      at com.ndh.junk.CastorUtil.unmarshal(CastorUtil.java:83)
      at com.ndh.junk.CastorUtil.unmarshal(CastorUtil.java:58)
      at com.ndh.junk.UnmarshalExample.main(UnmarshalExample.java:103)
>>>---- End Exception ----<<<

      at
org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:885)
      at
org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:918)
      at
org.apache.xerces.parsers.SAXParser.endElement(SAXParser.java:1403)
      at
org.apache.xerces.validators.common.XMLValidator.callEndElement(XMLValidator.jav
a:1436)
      at
org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher.dispatch(XMLDoc
umentScanner.java:1205)
      at
org.apache.xerces.framework.XMLDocumentScanner.parseSome(XMLDocumentScanner.java
:381)
      at org.apache.xerces.framework.XMLParser.parse(XMLParser.java:1035)
      at com.ndh.junk.CastorUtil.unmarshal(CastorUtil.java:83)
      at com.ndh.junk.CastorUtil.unmarshal(CastorUtil.java:58)
      at com.ndh.junk.UnmarshalExample.main(UnmarshalExample.java:103)
Exception in thread "main"

and now the real exception, that gets eaten--adding a line to print the
stack trace in the catch block of FieldHandlerImpl.setValue gets this:

java.lang.IllegalArgumentException: object is not an instance of declaring
class
      at java.lang.reflect.Method.invoke(Native Method)
      at
org.exolab.castor.mapping.loader.FieldHandlerImpl.setValue(FieldHandlerImpl.java
:468)
      at
org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:852)
      at
org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:918)
      at
org.apache.xerces.parsers.SAXParser.endElement(SAXParser.java:1403)
      at
org.apache.xerces.validators.common.XMLValidator.callEndElement(XMLValidator.jav
a:1436)
      at
org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher.dispatch(XMLDoc
umentScanner.java:1205)
      at
org.apache.xerces.framework.XMLDocumentScanner.parseSome(XMLDocumentScanner.java
:381)
      at org.apache.xerces.framework.XMLParser.parse(XMLParser.java:1035)
      at com.ndh.junk.CastorUtil.unmarshal(CastorUtil.java:83)
      at com.ndh.junk.CastorUtil.unmarshal(CastorUtil.java:58)
      at com.ndh.junk.UnmarshalExample.main(UnmarshalExample.java:103)

finally, I added some code to the FieldHandlerImpl.setValue immediately
before the call to setter.invoke that causes the exception, like this:

System.out.println("class of object whose setter is being invoked=" +
object.getClass());
System.out.println("setter method arg=" + value);
System.out.println("setter=" + setter);
setter.invoke( object, new Object[] { value == null ? _default : value } );

and got this:

class of object whose setter is being invoked=class
com.foo.persistent.TransactionSet
setter method arg=remark for user
setter=public void
com.foo.persistent.Transaction.setRemark(java.lang.String)

ps. here are the classes being mapped to. they are braindead, but I'm
including them for the sake of completeness.

package com.foo.persistent;
import java.util.*;
public class TransactionSet{
    private Set transactions = new HashSet();
    private String remark;
    public Set getTransactions(){return transactions;}
    public void setTransactions(Set transactions){this.transactions =
transactions;}
    public String getRemark(){return remark;}
    public void setRemark(String remark){this.remark = remark;}
}

package com.foo.persistent;
public class Transaction{
    private String remark;
    private String userId;
    public String getUserId(){return UserId;}
    public void setUserId(String userId){this.userId = userId;}
    public String getRemark(){return remark;}
    public void setRemark(String remark){this.remark = remark;}  
}    

----------------------------------------------------------- 
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
        unsubscribe castor-dev

Reply via email to