2

我在将 xml 流解组到实体时遇到问题。我的外键永远不会被设置为具有正确主键的对象,它们只是被设置为一个空对象。

具有外键的类称为 ProductBase。它引用了 BrandData(field pkId) 和 Categories(field pkId)。当我解组并坚持时,我可以很好地处理 BrandData 和 Categories。我遇到了 ProductBase 的问题。

这是产品库:

@XmlAccessorType(XmlAccessType.PROPERTY)
@Entity
@Table(name = "product_base")
@NamedQueries({
    @NamedQuery(name = "ProductBase.findAll", query = "SELECT p FROM ProductBase p"),
    @NamedQuery(name = "ProductBase.findByPkId", query = "SELECT p FROM ProductBase p WHERE p.pkId = :pkId"),
    @NamedQuery(name = "ProductBase.findByColorsAvail", query = "SELECT p FROM ProductBase p WHERE p.colorsAvail = :colorsAvail"),
    @NamedQuery(name = "ProductBase.findBySeriesName", query = "SELECT p FROM ProductBase p WHERE p.seriesName = :seriesName"),
    @NamedQuery(name = "ProductBase.findByStatusCodes", query = "SELECT p FROM ProductBase p WHERE p.statusCodes = :statusCodes"),
    @NamedQuery(name = "ProductBase.findByTs", query = "SELECT p FROM ProductBase p WHERE p.ts = :ts")})
public class ProductBase implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "pk_id")
    private Integer pkId;
    @Column(name = "colors_avail")
    private String colorsAvail;
    @Column(name = "series_name")
    private String seriesName;
    @Column(name = "status_codes")
    private String statusCodes;
    @Basic(optional = false)
    @Column(name = "ts")
    @Temporal(TemporalType.TIMESTAMP)
    private Date ts;
    @OneToMany(mappedBy = "productBase", fetch = FetchType.LAZY)
    private Collection<ProductSorts> productSortsCollection;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "productBase", fetch = FetchType.LAZY)
    private MapTarget mapTarget;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "productBase", fetch = FetchType.LAZY)
    private KeyFeatures keyFeatures;
    @JoinColumn(name = "pk_category", referencedColumnName = "pk_id")
    @ManyToOne( optional = false, fetch = FetchType.LAZY)
    private Categories categories;
    @JoinColumn(name = "pk_brand", referencedColumnName = "pk_id")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private BrandData brandData;
    @OneToMany(mappedBy = "productBase", fetch = FetchType.LAZY)
    private Collection<PromotionsByModel> promotionsByModelCollection;
    @OneToMany(mappedBy = "productBase", fetch = FetchType.LAZY)
    private Collection<ProductEnhancedFeatures> productEnhancementFeaturesCollection;
    @OneToMany(mappedBy = "productBase", fetch = FetchType.LAZY)
    private Collection<SkuBasic> skuBasicCollection;
    @OneToMany(mappedBy = "productBase", fetch = FetchType.LAZY)
    private Collection<ProductMeasurements> productMeasurementsCollection;

    public ProductBase() {
    }

    public ProductBase(Integer pkId) {
        this.pkId = pkId;
    }

    public ProductBase(Integer pkId, Date ts) {
        this.pkId = pkId;
        this.ts = ts;
    }

    @XmlElement(name = "pkID")
    public Integer getPkId() {
        return pkId;
    }

    public void setPkId(Integer pkId) {
        this.pkId = pkId;
    }

    @XmlElement(name = "ColorsAvail")
    public String getColorsAvail() {
        return colorsAvail;
    }

    public void setColorsAvail(String colorsAvail) {
        this.colorsAvail = colorsAvail;
    }

    @XmlElement(name = "SeriesName")
    public String getSeriesName() {
        return seriesName;
    }

    public void setSeriesName(String seriesName) {
        this.seriesName = seriesName;
    }

    @XmlElement(name = "StatusCodes")
    public String getStatusCodes() {
        return statusCodes;
    }

    public void setStatusCodes(String statusCodes) {
        this.statusCodes = statusCodes;
    }

    @XmlElement(name = "ts", required = true)
    @XmlSchemaType(name = "dateTime")
    public Date getTs() {
        return ts;
    }

    public void setTs(Date ts) {
        this.ts = ts;
    }

    @XmlTransient
    public Collection<ProductSorts> getProductSortsCollection() {
        return productSortsCollection;
    }

    public void setProductSortsCollection(Collection<ProductSorts> productSortsCollection) {
        this.productSortsCollection = productSortsCollection;
    }

    @XmlTransient
    public MapTarget getMapTarget() {
        return mapTarget;
    }

    public void setMapTarget(MapTarget mapTarget) {
        this.mapTarget = mapTarget;
    }

    @XmlTransient
    public KeyFeatures getKeyFeatures() {
        return keyFeatures;
    }

    public void setKeyFeatures(KeyFeatures keyFeatures) {
        this.keyFeatures = keyFeatures;
    }

    @XmlElement(name = "pkCategory")
    public Categories getCategories() {
        return categories;
    }

    public void setCategories(Categories categories) {
        this.categories = categories;
    }

    @XmlElement(name = "pkBrand")
    public BrandData getBrandData() {
        return brandData;
    }

    public void setBrandData(BrandData brandData) {
        this.brandData = brandData;
    }

    @XmlTransient
    public Collection<PromotionsByModel> getPromotionsByModelCollection() {
        return promotionsByModelCollection;
    }

    public void setPromotionsByModelCollection(Collection<PromotionsByModel> promotionsByModelCollection) {
        this.promotionsByModelCollection = promotionsByModelCollection;
    }

    @XmlTransient
    public Collection<ProductEnhancedFeatures> getProductEnhancementFeaturesCollection() {
        return productEnhancementFeaturesCollection;
    }

    public void setProductEnhancementFeaturesCollection(Collection<ProductEnhancedFeatures> productEnhancementFeaturesCollection) {
        this.productEnhancementFeaturesCollection = productEnhancementFeaturesCollection;
    }

    @XmlTransient
    public Collection<SkuBasic> getSkuBasicCollection() {
        return skuBasicCollection;
    }

    public void setSkuBasicCollection(Collection<SkuBasic> skuBasicCollection) {
        this.skuBasicCollection = skuBasicCollection;
    }

    @XmlTransient
    public Collection<ProductMeasurements> getProductMeasurementsCollection() {
        return productMeasurementsCollection;
    }

    public void setProductMeasurementsCollection(Collection<ProductMeasurements> productMeasurementsCollection) {
        this.productMeasurementsCollection = productMeasurementsCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (pkId != null ? pkId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof ProductBase)) {
            return false;
        }
        ProductBase other = (ProductBase) object;
        if ((this.pkId == null && other.pkId != null) || (this.pkId != null && !this.pkId.equals(other.pkId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "entities.cmic.ajrs.com.ProductBase[pkId=" + pkId + "]";
    }

解组以下内容:

<ProductBase>
<pkID>88294</pkID>
<pkBrand>18</pkBrand>
<pkCategory>35</pkCategory>
<ColorsAvail>W</ColorsAvail>
<StatusCodes/>
<ts>1970-01-01T05:22:35.06</ts>
</ProductBase>

我希望得到一个像这样的 ProductBase 对象:

ProductBase p1:
p1.pkId=88294
p1.brandData = (brandData object with pkId of 18)
p1.categories = (Categories object with pkId of 35)
p1.ts = (Date object with value 1970-01-01T05:22:35.06)

但是我得到

ProductBase p1: p1.pkId=88294 p1.brandData = (brandData object each field null) p1.categories = (Categories object each field null) p1.ts = (Date object with value 1970-01-01T05:22:35.06)

因此,当我坚持 ProductBase 时,它​​会遇到空值问题。

我希望这是由于 BradnData 和 Categories 实体中的引用不当造成的。我尝试使用 @XmlInverseReference 注释,但没有成功。任何人都看到问题可能是什么?

BrandData 实体:

@XmlAccessorType(XmlAccessType.PROPERTY)
@Entity
@Table(name = "brand_data")
@NamedQueries({
    @NamedQuery(name = "BrandData.findAll", query = "SELECT b FROM BrandData b"),
    @NamedQuery(name = "BrandData.findByPkId", query = "SELECT b FROM BrandData b WHERE b.pkId = :pkId"),
    @NamedQuery(name = "BrandData.findByCommonBrandId", query = "SELECT b FROM BrandData b WHERE b.commonBrandId = :commonBrandId"),
    @NamedQuery(name = "BrandData.findByCommonBrandName", query = "SELECT b FROM BrandData b WHERE b.commonBrandName = :commonBrandName"),
    @NamedQuery(name = "BrandData.findByTs", query = "SELECT b FROM BrandData b WHERE b.ts = :ts")})
public class BrandData implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "pk_id")
    private Integer pkId;
    @Column(name = "common_brand_id")
    private String commonBrandId;
    @Column(name = "common_brand_name")
    private String commonBrandName;
    @Basic(optional = false)
    @Column(name = "ts")
    @Temporal(TemporalType.TIMESTAMP)
    private Date ts;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "brandData", fetch = FetchType.LAZY)
    private Collection<ProductBase> productBaseCollection;

    public BrandData() {
    }

    public BrandData(Integer pkId) {
        this.pkId = pkId;
    }

    public BrandData(Integer pkId, Date ts) {
        this.pkId = pkId;
        this.ts = ts;
    }

    @XmlElement(name = "pkID")
    public Integer getPkId() {
        return pkId;
    }

    public void setPkId(Integer pkId) {
        this.pkId = pkId;
    }

    @XmlElement(name = "CommonBrandID")
    public String getCommonBrandId() {
        return commonBrandId;
    }

    public void setCommonBrandId(String commonBrandId) {
        this.commonBrandId = commonBrandId;
    }

    @XmlElement(name = "CommonBrandName")
    public String getCommonBrandName() {
        return commonBrandName;
    }

    public void setCommonBrandName(String commonBrandName) {
        this.commonBrandName = commonBrandName;
    }

    @XmlElement(required = true)
    @XmlSchemaType(name = "dateTime")
    public Date getTs() {
        return ts;
    }

    public void setTs(Date ts) {
        this.ts = ts;
    }

    @XmlInverseReference(mappedBy ="brandData")
    public Collection<ProductBase> getProductBaseCollection() {
        return productBaseCollection;
    }

    public void setProductBaseCollection(Collection<ProductBase> productBaseCollection) {
        this.productBaseCollection = productBaseCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (pkId != null ? pkId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof BrandData)) {
            return false;
        }
        BrandData other = (BrandData) object;
        if ((this.pkId == null && other.pkId != null) || (this.pkId != null && !this.pkId.equals(other.pkId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "entities.cmic.ajrs.com.BrandData[pkId=" + pkId + "]";
    }

类别实体:

@XmlAccessorType(XmlAccessType.PROPERTY)
@Entity
@Table(name = "categories")
@NamedQueries({
    @NamedQuery(name = "Categories.findAll", query = "SELECT c FROM Categories c"),
    @NamedQuery(name = "Categories.findByPkId", query = "SELECT c FROM Categories c WHERE c.pkId = :pkId"),
    @NamedQuery(name = "Categories.findByPkSuperCategory", query = "SELECT c FROM Categories c WHERE c.pkSuperCategory = :pkSuperCategory"),
    @NamedQuery(name = "Categories.findByCategoryId", query = "SELECT c FROM Categories c WHERE c.categoryId = :categoryId"),
    @NamedQuery(name = "Categories.findByCmicDescription", query = "SELECT c FROM Categories c WHERE c.cmicDescription = :cmicDescription"),
    @NamedQuery(name = "Categories.findByConsumerDescription", query = "SELECT c FROM Categories c WHERE c.consumerDescription = :consumerDescription"),
    @NamedQuery(name = "Categories.findByTs", query = "SELECT c FROM Categories c WHERE c.ts = :ts")})
public class Categories implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "pk_id")
    private Integer pkId;
    @Column(name = "pk_super_category")
    private Integer pkSuperCategory;
    @Column(name = "category_id")
    private String categoryId;
    @Column(name = "cmic_description")
    private String cmicDescription;
    @Column(name = "consumer_description")
    private String consumerDescription;
    @Basic(optional = false)
    @Column(name = "ts")
    @Temporal(TemporalType.TIMESTAMP)
    private Date ts;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "categories", fetch = FetchType.LAZY)
    private Collection<ProductBase> productBaseCollection;
    @JoinColumn(name = "pk_class", referencedColumnName = "pk_id")
    @ManyToOne(fetch = FetchType.LAZY)
    private Classes classes;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "categories", fetch = FetchType.LAZY)
    private SortFields sortFields;

    public Categories() {
    }

    public Categories(Integer pkId) {
        this.pkId = pkId;
    }

    public Categories(Integer pkId, Date ts) {
        this.pkId = pkId;
        this.ts = ts;
    }

    @XmlElement(name="pkID")
    public Integer getPkId() {
        return pkId;
    }

    public void setPkId(Integer pkId) {
        this.pkId = pkId;
    }


    public Integer getPkSuperCategory() {
        return pkSuperCategory;
    }

    public void setPkSuperCategory(Integer pkSuperCategory) {
        this.pkSuperCategory = pkSuperCategory;
    }

    @XmlElement(name = "Category_ID")
    public String getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(String categoryId) {
        this.categoryId = categoryId;
    }

    @XmlElement(name = "CMIC_Description")
    public String getCmicDescription() {
        return cmicDescription;
    }

    public void setCmicDescription(String cmicDescription) {
        this.cmicDescription = cmicDescription;
    }

    @XmlElement(name = "ConsumerDescription")
    public String getConsumerDescription() {
        return consumerDescription;
    }

    public void setConsumerDescription(String consumerDescription) {
        this.consumerDescription = consumerDescription;
    }

    @XmlElement(required = true)
    @XmlSchemaType(name = "dateTime")
    public Date getTs() {
        return ts;
    }

    public void setTs(Date ts) {
        this.ts = ts;
    }

    @XmlInverseReference(mappedBy ="categories")
    public Collection<ProductBase> getProductBaseCollection() {
        return productBaseCollection;
    }

    public void setProductBaseCollection(Collection<ProductBase> productBaseCollection) {
        this.productBaseCollection = productBaseCollection;
    }

    public Classes getClasses() {
        return classes;
    }

    public void setClasses(Classes classes) {
        this.classes = classes;
    }

    @XmlTransient
    public SortFields getSortFields() {
        return sortFields;
    }

    public void setSortFields(SortFields sortFields) {
        this.sortFields = sortFields;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (pkId != null ? pkId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Categories)) {
            return false;
        }
        Categories other = (Categories) object;
        if ((this.pkId == null && other.pkId != null) || (this.pkId != null && !this.pkId.equals(other.pkId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "entities.cmic.ajrs.com.Categories[pkId=" + pkId + "]";
    }
4

1 回答 1

2

对于这个用例,您将需要一个 XmlAdapter。

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class BrandDataAdapter extends XmlAdapter<Integer, BrandData> {

    @Override
    public Integer marshal(BrandData arg0) throws Exception {
        return arg0.getPkId();
    }

    @Override
    public BrandData unmarshal(Integer arg0) throws Exception {
        return new BrandData(arg0);
    }

}

在 ProductBase 中:

@JoinColumn(name = "pk_brand", referencedColumnName = "pk_id")
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@XmlJavaTypeAdapter(BrandDataApter.class)
private BrandData brandData;

了解更多信息

于 2011-04-21T13:51:13.427 回答