JAXB 在编组时展平实体列表

JAXB flatten list of entities when marshalling

我正在使用 JPA/Hibernate 作为我的持久性框架,并且我有以下实体层次结构:

@Entity
@Table(name = "node")
@XmlRootElement(name = "nodeMap")
@XmlAccessorType(XmlAccessType.FIELD)
public class NodeMapDTO {

    @XmlElementWrapper(name = "ipAddresses")
    @XmlElement(name = "ipAddress")
    @OneToMany
    @JoinColumn(name = "node_id")
    private List<IPAddressDTO> ipAddresses;

    [...]
}

@Entity
@Table(name = "node_ip_address")
@XmlAccessorType(XmlAccessType.FIELD)
public class IPAddressDTO {

    @Column(name = "ip_address")
    private String ipAddress;

    [...]
}

当我将 NodeMapDTO 转换为 XML 时,我得到以下结果:

<nodeMap>
   <ipAddresses>
      <ipAddress>
         <ipAddress>192.59.233.20</ipAddress>
      </ipAddress>
   </ipAddresses>
</nodeMap>

但我希望它是:

<nodeMap>
   <ipAddresses>
      <ipAddress>192.59.233.20</ipAddress>
   </ipAddresses>
</nodeMap>

不幸的是,我需要让我的 ipAddresses 字段成为 IPAddressDTOs 而不是 Strings 的列表,否则我无法使用 @OneToMany 注释(而且我不出于性能原因不想使用@ElementCollection)。

我也想尝试这样做而不必创建任何额外的包装器 classes。我想如果我为 List<IPAddressDTO> ipAddresses 字段创建一个包装器 class,我的 Hibernate 注释将不起作用,它只会使代码比它需要的复杂得多。

谢谢大家

@XmlValue.

注释字段 ipAddress

这里是完整的 Minimal, Reproducible Example:

import java.util.*;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
public class Test {
    public static void main(String[] args) throws Exception {
        Marshaller marshaller = JAXBContext.newInstance(NodeMapDTO.class).createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(new NodeMapDTO(new IPAddressDTO("192.59.233.20")), System.out);
    }
}
@XmlRootElement(name = "nodeMap")
@XmlAccessorType(XmlAccessType.FIELD)
public class NodeMapDTO {
    @XmlElementWrapper(name = "ipAddresses")
    @XmlElement(name = "ipAddress")
    private List<IPAddressDTO> ipAddresses;

    NodeMapDTO() {
    }
    NodeMapDTO(IPAddressDTO... ipAddresses) {
        this.ipAddresses = Arrays.asList(ipAddresses);
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
public class IPAddressDTO {
    @XmlValue
    private String ipAddress;

    IPAddressDTO() {
    }
    IPAddressDTO(String ipAddress) {
        this.ipAddress = ipAddress;
    }
}

输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<nodeMap>
    <ipAddresses>
        <ipAddress>192.59.233.20</ipAddress>
    </ipAddresses>
</nodeMap>