【问题标题】:JAXB (Moxy) XML Metadata mapping issueJAXB (Moxy) XML 元数据映射问题
【发布时间】:2012-08-03 19:24:33
【问题描述】:

我正在尝试使用 Moxy 的 XML 元数据扩展来映射以下界面。但是当我尝试加载它时,我收到以下错误。我无法将公共构造函数添加到 AddressType,因为它是一个枚举。

我的问题是:为什么 Moxy impl 会查看 AddressType,即使我没有在 xml 元数据中指定?

public interface TokenizedUnitedStatesAddress
{
    class AddressType extends Enum
    {
        public static final AddressType STREET = new AddressType("street");    
        public static final AddressType PO_BOX = new AddressType("poBox");    
        public static final AddressType RURAL_ROUTE = new AddressType("ruralRoute");

        public static AddressType getEnum(final String type)
        {
            return (AddressType) getEnum(AddressType.class, type);
        }

        protected AddressType(final String name)
        {
            super(name);
        }
    }

    String getApartmentNumber();

    //removed other getters for brevity
}

<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_4.xsd"
   version="2.4" package-name="com.abc.ic.domain.country.us">
   <java-types>
      <java-type name="TokenizedUnitedStatesAddress">
         <xml-root-element />
         <xml-type
            prop-order="StreetPreDirection StreetNumber StreetName StreetType StreetPostDirection UnitDesignator UnitNumber AddressLine1 AddressLine2 City State PostalCode CarrierRoute LengthAtAddress OwnershipStatus" />
         <java-attributes>
            <xml-element name="StreetPreDirection" java-attribute="preDirectional" />
            <xml-element name="StreetNumber" java-attribute="houseNumber" />
            <xml-element name="StreetName" java-attribute="streetName" />
            <xml-element name="StreetType" java-attribute="streetType" />
            <xml-element name="StreetPostDirection" java-attribute="postDirection" />
            <xml-element name="UnitNumber" java-attribute="apartmentNumber" />
            <xml-element name="AddressLine1" java-attribute="primaryAddress" />
            <xml-element name="AddressLine2" java-attribute="secondaryAddress" />
            <xml-element name="City" java-attribute="cityName" />
            <xml-element name="State" java-attribute="stateAbbreviation" />
            <xml-element name="PostalCode" java-attribute="zipCode" />
         </java-attributes>
      </java-type>
   </java-types>
</xml-bindings>

javax.xml.bind.JAXBException: 
Exception Description: The class com.abc.ic.domain.country.us.TokenizedUnitedStatesAddress$AddressType requires a zero argument constructor or a specified factory method.  Note that non-static inner classes do not have zero argument constructors and are not supported.
 - with linked exception:
[Exception [EclipseLink-50001] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The class com.abc.ic.domain.country.us.TokenizedUnitedStatesAddress$AddressType requires a zero argument constructor or a specified factory method.  Note that non-static inner classes do not have zero argument constructors and are not supported.]
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:908)
    at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:157)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:170)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:157)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:117)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:107)

【问题讨论】:

  • 这可能是一个错误,您能否在以下位置输入一个:bugs.eclipse.org/bugs/enter_bug.cgi?product=EclipseLink
  • “即使使用 XML 来提供元数据,Mxoy Impl 仍在自省该类” - 这是正确的错误摘要吗?另外,如果您能解释正在发生的事情作为这个问题的答案,那就太好了。
  • 另外,如果你能提供我应该研究哪个类,我可以为你修复这个错误
  • 外部映射文件用于扩充注释提供的元数据。它也可以用来完全替换它(参见:blog.bdoughan.com/2011/09/…)。似乎 MOXy 正在尝试将枚举作为域类进行处理。 org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor` 可能是罪魁祸首。我们将不胜感激您希望提交的任何补丁。我希望我现在能得到更多的帮助,但我要出城了。您也可以在 EclipseLink 论坛发帖:eclipse.org/forums/index.php?t=thread&frm_id=111
  • 好的。但 AddressType 不是 Java 5 枚举。它是 commons-lang 的 Enum 抽象。

标签: jaxb eclipselink moxy


【解决方案1】:

即使 XML 用于提供元数据,Mxoy impl 仍会内省该类。这是因为,根据设计,外部映射文件用于扩充注释提供的元数据。

然而,问题是公共领域的枚举抽象要求我们为枚举提供一个非公共的单参数构造函数。我通过添加一个初始化默认枚举的公共无参数构造函数来解决此问题。这对我的应用程序来说已经足够了。但是,我创建了一个可以关注here 的错误。

注意:我也查看了foctory-method option of Moxy,但它需要一个空的 arg 方法作为工厂方法,而 Enum 则不是这种情况。

【讨论】:

    【解决方案2】:

    我是 EclipseLink MOXy 团队的开发人员,我一直在研究这个问题。您对 AddressType 类进行自省的原因是正确的,我看到您有一个解决方法。

    另一种解决方案是创建一个 XmlAdapter,它可以在 Apache Enum 类和它们的 XML(字符串)表示之间进行转换,如下所示:

    import javax.xml.bind.annotation.adapters.XmlAdapter;
    
    import org.apache.commons.lang.enums.Enum;
    
    import enumbindings.TokenizedUnitedStatesAddress.AddressType;
    
    public class ApacheEnumAdapter extends XmlAdapter<String, Enum> {
    
        public ApacheEnumAdapter() {
        }
    
        @Override
        public Enum unmarshal(String s) throws Exception {
            return AddressType.getEnum(s);
        }
    
        @Override
        public String marshal(Enum e) throws Exception {
            if (null == e) {
                return null;
            }
            return e.getName();
        }
    
    }
    

    然后像这样在绑定文件中连接适配器:

    ...
    <xml-element name="StreetType" java-attribute="streetType">
        <xml-java-type-adapter value="enumbindings.ApacheEnumAdapter" />
    </xml-element>
    ...
    

    就您输入的错误而言,EclipseLink 在这种情况下实际上表现正确,我们不对 Apache Commons 类进行任何特殊处理,因此仍然需要默认的无参数构造函数(或其他一些处理机制)。不过,我会更新您的错误并将其更改为增强请求以支持开箱即用的 Apache 枚举,我们将对其进行评估。

    谢谢,

    瑞克

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多