I stuck on this Date conversation error for quite some time ...
I am using eclipselinks, openJPA under TomcatEE environment, and trying to use jaxb doing marshalling. I met a problem for marshall one JPA object, which contains Date, TimeStamp elements.
The exception message is ---
javax.xml.bind.MarshalException
- with linked exception:
[Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [3/19/12 12:00 AM], of class [class org.apache.openjpa.util.java$util$Date$proxy], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[createTs-->createTs/text()]] with descriptor [XMLDescriptor(xxx.xxxx.xxx.xxxx.entities.ApplicationEntity --> [])], could not be converted to [class java.util.Date].]
The strange thing is jaxb converting works OK for some customers, but not some other customer. I tried to put @XmlElement(type=Date.class) for this field crtTs, It doesn't work.
Thanks for your help in advance.
LL
I have been able to reproduce the issue you are seeing. You can use the following bug to track our progress on this issue:
- http://bugs.eclipse.org/383639
WORK AROUND
DateAdapter
You could use an XmlAdapter
to convert the problematic date into a proper java.util.Date
.
package forum11145711;
import java.util.Date;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class DateAdapter extends XmlAdapter<Date, Date>{
@Override
public Date unmarshal(Date date) throws Exception {
return date;
}
@Override
public Date marshal(Date date) throws Exception {
if(null == date) {
return date;
}
return new Date(date.getTime());
}
}
Root
The @XmlJavaTypeAdapter
annotation is used to leverage the XmlAdapter
:
package forum11145711;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Root {
private Date date;
@XmlJavaTypeAdapter(DateAdapter.class)
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
MyDate
Below is the subclass of java.util.Date
I'm using in this example.
package forum11145711;
import java.util.Date;
public class MyDate extends Date {
}
Demo
Below is some demo code you can use to prove that everything works:
package forum11145711;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Root root = new Root();
root.setDate(new MyDate());
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
Output
<?xml version="1.0" encoding="UTF-8"?>
<root>
<date>2012-06-27T10:39:49.081</date>
</root>