1

我有一堂课叫Building.

它有一个BuildingBenchAssociation记录列表 ( List<BuildingBenchAssociation> benches)

BuildingBenchAssociation有一个由buildingId和组成的复合 IDbenchId 该 ID 由单独的类表示,该类BuildingBenchAssociationPK只有两个属性 -buildingIdbenchId

这是我编组Building实例时得到的输出

<building buildingId="9">
<benches>
DOMRecord(<?xml version="1.0" encoding="UTF-8"?><buildingBenchAssociation><benchId>245865</benchId><buildingId>9</buildingId></buildingBenchAssociation>)
</benches>
<benches>
DOMRecord(<?xml version="1.0" encoding="UTF-8"?><buildingBenchAssociation><benchId>245866</benchId><buildingId>9</buildingId></buildingBenchAssociation>)
</benches>
<benches>

但我不想DOMRecord(<?xml version="1.0" encoding="UTF-8"?>出现在输出中。所需的输出是这样的:

<building buildingId="9">
<benches>
<buildingBenchAssociation><benchId>245865</benchId><buildingId>9</buildingId></buildingBenchAssociation>
</benches>
<benches>
<buildingBenchAssociation><benchId>245866</benchId><buildingId>9</buildingId></buildingBenchAssociation>
</benches>
<benches>

出了什么问题,我该如何纠正?我正在使用 Eclipselink MOXy 库。

参考类:

1级

@Entity
@Table(name="building")
@XmlRootElement
public class Building implements Serializable {
....

private List<BuildingBenchAssociation> benchs = new ArrayList<BuildingBenchAssociation>();

    @XmlIDREF
    @OneToMany(mappedBy="building")
    public List<BuildingBenchAssociation> getBenchs() {
        return benchs;
    }

    public void setBenchs(List<BuildingBenchAssociation> benchs) {
        this.benchs = benchs;
    }
}

2 级

@Entity
@Table(name="building_bench_rel")
@XmlRootElement
public class BuildingBenchAssociation implements Serializable {
    private static final long serialVersionUID = 1L;
    private BuildingBenchAssociationPK idx;

    private Bench bench;
    private Building building;
    private byte alertFlags;
    private byte status;

    public BuildingBenchAssociation() {
            idx=new BuildingBenchAssociationPK();
    }

    @XmlID
    @XmlPath(".")
    @Id
    public BuildingBenchAssociationPK getIdx() {
        return this.idx;
    }

    public void setIdx(BuildingBenchAssociationPK id) {
        this.idx = id;
    }

    @Column(name="ALERT_FLAGS")
    public byte getAlertFlags() {
        return this.alertFlags;
    }

    public void setAlertFlags(byte alertFlags) {
        this.alertFlags = alertFlags;
    }

    @Column(name="STATUS", insertable=false, updatable=false)
    public byte getStatus() {
        return this.status;
    }

    public void setStatus(byte status) {
        this.status = status;
    }

    @XmlIDREF
    @ManyToOne
    @JoinColumn(name="BENCH_ID",insertable=false,updatable=false)
    public Bench getBench() {
        return bench;
    }


    public void setBench(Bench bench) {
        this.bench = bench;
        this.idx.setBenchId(bench==null?null:bench.getBenchId());
    }

    @XmlIDREF
    @ManyToOne
    @JoinColumn(name="BUILDING_ID",insertable=false,updatable=false)
    public Building getBuilding() {
        return building;
    }

    public void setBuilding(Building building) {
        this.building = building;
        this.idx.setBuildingId(building==null?null:building.getBuildingId());
    }

}

3 级

@Embeddable
@XmlRootElement
public class BuildingBenchAssociationPK implements Serializable {
...

    private Integer buildingId;
    private Integer benchId;

    public BuildingBenchAssociationPK() {
    }

    @XmlKey
    @Column(name="BUILDING_ID")
    public Integer getBuildingId() {
        return this.buildingId;
    }
    public void setBuildingId(Integer buildingId) {
        this.buildingId = buildingId;
    }

    @XmlKey
    @Column(name="BENCH_ID")
    public Integer getBenchId() {
        return this.benchId;
    }
    public void setBenchId(Integer benchId) {
        this.benchId = benchId;
    }
}
4

1 回答 1

2

以下是当前如何使用 MOXy 映射此用例。我已打开以下增强请求以使此用例更易于映射:


参考对象

嵌入式 ID (EmployeeId)

下面是一个嵌入式 ID 类的示例:

import java.math.BigDecimal;
import javax.persistence.*;
import javax.xml.bind.annotation.*;

@Embeddable
@XmlAccessorType(XmlAccessType.FIELD)
public class EmployeeId {

    @Column(name="E_ID")
    BigDecimal eId;

    String country;

}

具有嵌入式 ID 的类(员工)

我们希望使用嵌入的 ID 类作为 XML 关系中的键。目前 MOXy 不允许通过注释完成此操作,因此我们将利用@XmlCustomizer注释以编程方式修改元数据。

import java.util.List;
import javax.persistence.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

@Entity
@IdClass(EmployeeId.class)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlCustomizer(EmployeeCustomizer.class)
public class Employee {

    @EmbeddedId
    @XmlPath(".")
    EmployeeId id;

    @OneToMany(mappedBy="contact")
    List<PhoneNumber> contactNumber;

}

为员工自定义映射元数据 (EmployeeCustomizer)

在定制器类中,我们将为构成嵌入类键的映射指定 XPath。

import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;

public class EmployeeCustomizer implements DescriptorCustomizer {

    @Override
    public void customize(ClassDescriptor descriptor) throws Exception {
        descriptor.addPrimaryKeyFieldName("eId/text()");
        descriptor.addPrimaryKeyFieldName("country/text()");
    }

}

引用对象

电话号码

我们还需要以编程方式添加基于复合键的映射,因此我们将再次使用@XmlCustomizer注释。

import javax.persistence.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

@Entity
@XmlAccessorType(XmlAccessType.FIELD)
@XmlCustomizer(PhoneNumberCustomizer.class)
public class PhoneNumber {

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
        @JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
    })
    Employee contact;

}

自定义 PhoneNumber 的映射元数据 (PhoneNumberCustomizer)

在此定制器中,我们将删除默认映射,并基于复合键以编程方式创建新映射。

import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;

public class PhoneNumberCustomizer  implements DescriptorCustomizer {

    @Override
    public void customize(ClassDescriptor descriptor) throws Exception {
        descriptor.removeMappingForAttributeName("contact");

        XMLObjectReferenceMapping contactMapping = new XMLObjectReferenceMapping();
        contactMapping.setAttributeName("contact");
        contactMapping.setReferenceClass(Employee.class);
        contactMapping.addSourceToTargetKeyFieldAssociation("contact/@eID", "eId/text()");
        contactMapping.addSourceToTargetKeyFieldAssociation("contact/@country", "country/text()");
        descriptor.addMapping(contactMapping);
    }

}

演示代码

以下演示代码可用于演示一切正常:

演示

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Employee.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Employee employee = (Employee) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(employee, System.out);
    }

}

输入.xml/输出

<?xml version="1.0" encoding="UTF-8"?>
<employee>
   <eId>10</eId>
   <country>Canada</country>
   <contactNumber>
      <contact eID="10" country="Canada"/>
   </contactNumber>
   <contactNumber>
      <contact eID="10" country="Canada"/>
   </contactNumber>
</employee>

了解更多信息

于 2013-05-07T18:41:31.070 回答