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
字段成为 IPAddressDTO
s 而不是 String
s 的列表,否则我无法使用 @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>
我正在使用 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
字段成为 IPAddressDTO
s 而不是 String
s 的列表,否则我无法使用 @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>