如何使用JPA持久化XMLGregorianCalendar?

时间:2015-02-08 12:53:07

标签: hibernate soap cxf

这就是我所拥有的:

@XmlSchemaType(name = "dateTime")
@Column(name = "expiry-date", nullable = false)
protected XMLGregorianCalendar expiryDate;

抛出以下异常:

org.hibernate.MappingException: Could not determine type for: javax.xml.datatype.XMLGregorianCalendar

谢谢

3 个答案:

答案 0 :(得分:4)

JPA不支持

XMLGregorianCalendar,您可以使用java.util.Datejava.util.Calendar(解释为here)。

也许您可以查看项目Hyperjaxb3(为JAXB对象提供关系持久性)。 Here它解释了如何处理时态属性:

  

时间属性(键入xsd:dateTime,xsd:date,xsd:time等)   将被映射为时间JPA属性。 Hyperjaxb3会选择   临时类型为TIMESTAMP,DATE或TIME,具体取决于XML Schema   时间属性的类型。时间属性通常是   映射到JPA不支持的XMLGregorianCalendar - 和   因此必须包装:

<xs:element name="dateTime" type="xs:dateTime" minOccurs="0"/>

@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar dateTime;
@Transient
public XMLGregorianCalendar getDateTime() {
    return dateTime;
}
public void setDateTime(XMLGregorianCalendar value) {
    this.dateTime = value;
}
@Basic
@Column(name = "DATETIMEITEM")
@Temporal(TemporalType.TIMESTAMP)
public Date getDateTimeItem() {
    return XmlAdapterUtils.unmarshall(XMLGregorianCalendarAsDateTime.class, this.getDateTime());
}

public void setDateTimeItem(Date target) {
    setDateTime(XmlAdapterUtils.marshall(XMLGregorianCalendarAsDateTime.class, target));
}

另一种方法是编写自己的解决方案,执行一些转换,而不是试图保留JAXB对象。

答案 1 :(得分:1)

您可以在不使用任何其他框架的情况下完成此操作。例如:

@Transient
@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar expiryDate;

@Column(name = "expiry-Date", nullable = false)
public Calendar getExpiryDateToCalendar() {
    return new GregorianCalendar(expiryDate.getYear(), expiryDate.getMonth(), expiryDate.getDay());
}

答案 2 :(得分:1)

这是一个工作示例。您还应该注意代码中的几个月,因为XMLGregorianCalendar月份定义为1到12,但是在日历中 - 从0到11。

@Entity
@Access(AccessType.FIELD)
@Table(name="test_my_entity")
public class MyEntity {

    @Id
    @GeneratedValue
    private Long id;

    @XmlAttribute(name = "name")
    @Transient
    protected String name;

    @XmlSchemaType(name = "dateTime")
    @Transient
    protected XMLGregorianCalendar myXMLDate;

    @Transient
    private Calendar calendarDate;

    @Access(AccessType.PROPERTY)
    @Column(name = "calendar_date")
    private Calendar getCalendarDate() {
        return new GregorianCalendar(myXMLDate.getYear(), myXMLDate.getMonth()-1, myXMLDate.getDay());
    }

    @Access(AccessType.PROPERTY)
    @Column(name = "my_str_name")
    public String getName() {
        return "My string";
    }

    //...setters here

    public MyEntity() {
    }
}