【问题标题】:Unmarshalling to inner static class fields解组到内部静态类字段
【发布时间】:2014-08-04 17:08:51
【问题描述】:

我有一个带有复合键的实体类,它是实体的公共静态内部类。我想解组文件并将值放入内部类的字段中。

我用@XmlKey、@XmlPath、@XmlJoinNode 尝试了几件事,但都没有奏效,我什至不确定我的方法是否正确。

我的 xml 文件:

<?xml version="1.0" encoding="UTF-8"?>

<numbers>
    <one>one_text</one>
    <two>two_text</two>
    <three>three_text</three>
    <four>four_text</four>
</numbers>

我的班级:

@XmlRootElement(name = "numbers")
public class Numbers {

    public static class Id {

        @XmlElement
        private String one;

        @XmlElement
        private String two;

        public String getOne() {
            return one;
        }

        public void setOne(String one) {
            this.one = one;
        }

        public String getTwo() {
            return two;
        }

        public void setTwo(String two) {
            this.two = two;
        }
    }

    @XmlElement
    private String three;

    @XmlElement
    private String four;

    private Id id = new Id();

    public String getThree() {
        return three;
    }

    public void setThree(String three) {
        this.three = three;
    }

    public String getFour() {
        return four;
    }

    public void setFour(String four) {
        this.four = four;
    }

    public Id getId() {
        return id;
    }

    public void setId(Id id) {
        this.id = id;
    }    
}

不用担心缺少 JPA 注释。感谢您的回答。

更新

精度:XML 文件不能被修改,如果没有办法保留这样的东西,java 类可能是这样,但它必须可以被 hibernate 解释为具有复合主键的实体。

使用 MOXy 的解决方案

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name = "numbers")
@XmlAccessorType(XmlAccessType.FIELD)
@Entity
public class Numbers {

    @Embeddable
    public static class Id implements Serializable {

        private static final long serialVersionUID = -2153062768685935342L;

        @Column
        @XmlElement
        private String one;

        @Column
        @XmlElement
        private String two;

        public String getOne() {
            return one;
        }

        public void setOne(String one) {
            this.one = one;
        }

        public String getTwo() {
            return two;
        }

        public void setTwo(String two) {
            this.two = two;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((one == null) ? 0 : one.hashCode());
            result = prime * result + ((two == null) ? 0 : two.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Id other = (Id) obj;
            if (one == null) {
                if (other.one != null)
                    return false;
            } else if (!one.equals(other.one))
                return false;
            if (two == null) {
                if (other.two != null)
                    return false;
            } else if (!two.equals(other.two))
                return false;
            return true;
        }
    }

    @Column
    @XmlElement
    private String three;

    @Column
    @XmlElement
    private String four;

    @EmbeddedId
    @XmlPath(".")
    private Id id = new Id();


    public String getThree() {
        return three;
    }

    public void setThree(String three) {
        this.three = three;
    }


    public String getFour() {
        return four;
    }

    public void setFour(String four) {
        this.four = four;
    }

    public Id getId() {
        return id;
    }

    public void setId(Id id) {
        this.id = id;
    }
}

MOXy 的替代品

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@XmlRootElement(name = "numbers")
@XmlAccessorType(XmlAccessType.FIELD)
@Entity
public class Numbers {

    @Embeddable
    public static class Id implements Serializable {

        private static final long serialVersionUID = -2153062768685935342L;

        @Column
        private String one;

        @Column
        private String two;

        public String getOne() {
            return one;
        }

        public void setOne(String one) {
            this.one = one;
        }

        public String getTwo() {
            return two;
        }

        public void setTwo(String two) {
            this.two = two;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((one == null) ? 0 : one.hashCode());
            result = prime * result + ((two == null) ? 0 : two.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Id other = (Id) obj;
            if (one == null) {
                if (other.one != null)
                    return false;
            } else if (!one.equals(other.one))
                return false;
            if (two == null) {
                if (other.two != null)
                    return false;
            } else if (!two.equals(other.two))
                return false;
            return true;
        }
    }

    @Column
    @XmlElement
    private String three;

    @Column
    @XmlElement
    private String four;

    @EmbeddedId
    @XmlTransient
    private Id id = new Id();


    public String getThree() {
        return three;
    }

    public void setThree(String three) {
        this.three = three;
    }


    public String getFour() {
        return four;
    }

    public void setFour(String four) {
        this.four = four;
    }

    public Id getId() {
        return id;
    }

    public void setId(Id id) {
        this.id = id;
    }

    @XmlElement
    public String getOne() {
        return id.getOne();
    }

    public void setOne(String one) {
        id.setOne(one);
    }

    @XmlElement
    public String getTwo() {
        return id.getTwo();
    }

    public void setTwo(String two) {
        id.setTwo(two);
    }
}

【问题讨论】:

    标签: java jaxb moxy


    【解决方案1】:

    由于您的问题被标记为 [moxy],您可以按如下方式使用 MOXy 的 @XmlPath 扩展来获得所需的行为。

    @XmlPath(".")
    private Id id = new Id();
    

    【讨论】:

    • 是的,我在这个项目中使用 MOXy,您的解决方案正是我正在寻找的。​​span>
    【解决方案2】:

    可以与您的班级编号(未)编组的 XML 是这样的:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <numbers>
      <three>tres</three>
      <four>quattro</four>
      <id>
        <one>uno</one>
        <two>due</two>
      </id>
    </numbers>
    

    这是数字,添加了一些注释,与以前一样省略:

    @XmlRootElement(name = "numbers")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Numbers {
    
        @XmlAccessorType(XmlAccessType.FIELD)
        public static class Id {
            @XmlElement
            private String one;
            @XmlElement
            private String two;
            // getters, setters
         }
    
        @XmlElement
        private String three;
        @XmlElement
        private String four;
        @XmlElement
        private Id id = new Id();
        // getters, setters
    }
    

    实现

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <numbers>
      <four>quattro</four>
      <one>uno</one>
      <three>tres</three>
      <two>due</two>
    </numbers>
    

    您可以将所有字段放入数字中:

    @XmlRootElement(name = "numbers")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Numbers {
        @XmlElement
        private String one;
        @XmlElement
        private String two;
        @XmlElement
        private String three;
        @XmlElement
        private String four;
        // getters, setters
    }
    

    或者您可以委托:

    @XmlRootElement(name = "numbers")
    @XmlAccessorType(XmlAccessType.PROPERTY)
    public class Numbers {
    
    public static class Id {
        private String one;
        private String two;
        // getters, setters
    }
    
    private String three;
    private String four;
    private Id id = new Id();
    
    @XmlElement
    public String getThree() {
        return three;
    }
    public void setThree(String three) {
        this.three = three;
    }
    @XmlElement
    public String getFour() {
        return four;
    }
    public void setFour(String four) {
        this.four = four;
    }
    @XmlTransient
    public Id getId() {
        return id;
    }
    public void setId(Id id) {
        this.id = id;
    }    
    @XmlElement
    public String getOne() {
        return id.getOne();
    }
    public void setOne(String one) {
        id.setOne( one );
    }
    @XmlElement
    public String getTwo() {
        return id.getTwo();
    }
    public void setTwo(String two) {
        id.setTwo( two );
    }
    }
    

    【讨论】:

    • 不幸的是,xml 文件结构必须保持与发布的相同。如果可能,我想保留班级结构,但不是强制性的。
    • 好吧,那就忘掉内部类,做一个和两个数字字段。 - 将此添加到我的答案中。
    • 我的班级是一个具有复合 PK 的实体。不能这样构成。
    • 可能可以编写一个适配器,从没有内部类的 Number 到具有该内部类的 NumberX。但只有当你真的、真的需要它时……
    • 委托版本似乎不起作用。编辑:我的意思是一/两个字段仍然为空。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 2021-04-21
    • 2017-11-06
    • 2015-09-25
    • 2013-03-12
    相关资源
    最近更新 更多