2017-09-13 16 views
0

私はマーシャリングをテストし、次のJavaオブジェクトを非整列化しています:JAXB非整列化コレクション(セット)

Frameworkクラス:

@XmlRootElement (name = "framework") 
@XmlAccessorType(XmlAccessType.FIELD) 
@Entity 
public class Framework implements Comparable<Framework>, Serializable { 
    private static final long serialVersionUID = 1L; 
    @XmlTransient 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String frameworkName; 
    private String frameworkVersion; 
    private String frameworkDescription; 
    @XmlElementWrapper(name = "framework-domains") 
    private Set<FrameworkDomain> frameworkDomainList = new HashSet<>(); 
    @XmlElementWrapper(name = "framework-comments") 
    private Set<Comment> comments = new HashSet<>(); 

(唯一のゲッター、セッターと任意の追加の注釈のない機能のnuberが含まれています)

ドメインクラス:

@XmlRootElement(name = "domain") 
@XmlAccessorType(XmlAccessType.FIELD) 
@Entity 
public class FrameworkDomain implements Comparable<FrameworkDomain>, Serializable { 

    private static final long serialVersionUID = 1L; 
    @XmlTransient 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String domainName; 
    private String domainDescription; 
    @XmlElementWrapper(name = "domain-requirements") 
    private Set<Requirement> domainRequirements = new HashSet<>(); 
    @XmlElementWrapper(name = "domain-comments") 
    private Set<Comment> domainComments = new HashSet<>(); 

要件CLA SS:

@XmlRootElement(name = "requirement") 
@XmlAccessorType(XmlAccessType.FIELD) 
@Entity 
public class Requirement implements Comparable<Requirement>, Serializable { 

    private static final long serialVersionUID = 1L; 
    @XmlTransient 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String requirementName; 
    private String requirementDescription; 
    private String requirementGuidance; 
    @XmlElementWrapper(name = "sub-requirements") 
    private Set<Requirement> requirementSubrequirementList = new HashSet<>(); 
    @XmlElementWrapper(name = "testing-procedures") 
    private Set<TestingProcedure> requirementTestingProceduresList = new HashSet<>(); 
    @XmlElementWrapper(name = "requirement-comments") 
    private Set<Comment> comments = new HashSet<>(); 

マーシャリングとマーシャリング解除コード:

public static String exportFramework(Framework f) { 
    java.io.StringWriter s = new java.io.StringWriter(); 
    try { 
     JAXBContext jc = JAXBContext.newInstance(Framework.class); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8"); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     marshaller.marshal(f, s); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 

    return s.toString(); 
} 

public static Framework importFramework(java.io.InputStream xml) { 
    intelicompliance.model.Framework f = null; 

    try { 
     JAXBContext jc = JAXBContext.newInstance(Framework.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     f = (intelicompliance.model.Framework) unmarshaller.unmarshal(xml); 
    } catch (JAXBException ex) { 
     ex.printStackTrace(); 
    } 

    return f; 
} 

私は、私が作成したオブジェクトをマーシャリングするとき、それは次のXMLを生成します。

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<framework> 
    <frameworkName>PCI DSS</frameworkName> 
    <frameworkVersion>3.3</frameworkVersion> 
    <frameworkDescription>The Payment Card Industry Data Security Standard (PCI DSS) is a proprietary information security standard for organizations that handle branded credit cards from the major card schemes including Visa, MasterCard, American Express, Discover, and JCB.</frameworkDescription> 
    <framework-domains> 
     <frameworkDomainList> 
      <domainName>Domain 1a</domainName> 
      <domainDescription>Build and Maintain a Secure Network and Systems</domainDescription> 
      <domain-requirements></domain-requirements> 
      <domain-comments></domain-comments> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 2a</domainName> 
      <domainDescription>Protect Cardholder Data</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 3a</domainName> 
      <domainDescription>Maintain a Vulnerability Management Program</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 4a</domainName> 
      <domainDescription>Implement Strong Access Control Measures</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 5a</domainName> 
      <domainDescription>Regularly Monitor and Test Networks</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 6a</domainName> 
      <domainDescription>Maintain an Information Security Policy</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
    </framework-domains> 
    <framework-comments/> 
</framework> 

...まさにしています私は期待している。

しかし、XMLをオブジェクトに変換しようとすると、ドメインの1つだけがセットに含まれます。つまり、インポート(アンマーシャリング)プロセスで最初のノードの後に​​XMLノードが無視されます。

なぜ誰かが考えているのですか?または、私は何を間違っているのですか?

UPDATE は私が変更することにより、いくつかの進歩を遂げている。

private Set<FrameworkDomain> frameworkDomainList = new HashSet<>(); 

に:予想通り、今、すべての子要素をインポート

private List<FrameworkDomain> frameworkDomainList = new LinkedList<>(); 

。しかし、私は本当にセットを使用することを好む。

JAXBはリストとは異なるセットを扱いますか?私の質問への答えに基づいて

+0

オブジェクトにhashCode()メソッドを正しく設定しましたか? –

+0

「適切に」とはどういう意味なのか分かりませんが、ここにコードがあります: @Override public int hashCode(){ int hash = 0; ハッシュ+ =(id!= null?id.hashCode():0); 戻りハッシュ; } – JohnMarkh

答えて

0

何私が正しくによって意味することは、あなたが同じでないすべてのオブジェクトが異なるハッシュを返すことが保証ということです。

あなたの問題は、アンマーシャリングしているすべてのオブジェクトが同じhashCodeを持っているという事実から来ています。したがって、すべての要素が等しいとみなし、1つだけ保持します(最後の1つのJAXBが処理します。

idsのないオブジェクトをHashSetに追加することで、この動作を確認できるはずです。最後のものだけを保持する必要があります。

また、リンクリストに切り替えるときにリストにデータが入力される理由についても説明します。

異なるhashCodeメソッドを使用するか、IDをマーシャリングして問題を解決してください。

hashCode()メソッドとともにequals()メソッドをオーバーライドし、a.equals(b)およびa.hashCode == b.hashCodeが常に同じ結果を返すようにする必要があります。

+0

あなた、私の友人は、学者と紳士です!問題とその解決策を特定しました。 – JohnMarkh

関連する問題