2011-04-21 30 views
2

我解組XML流的實體的問題。我的外鍵永遠不會被設置爲具有正確主鍵的對象,它們只會被設置爲一個emtpy對象。JAXB解組到實體錯誤

與外鍵的類被稱爲ProductBase。它具有對品牌數據(字段pkId)和類別(字段pkId)的引用。當我解組並堅持時,我可以很好地處理BrandData和類別。我遇到了ProductBase的問題。

這裏是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 =(品牌數據對象每個字段爲空) p1.categories =(類別對象每個字段爲空) p1.ts =(帶值爲1970-01-01T05的日期對象: 22:35.06)

所以,當我去堅持它與空值的問題ProductBase。

我希望這是由於在BradnData和分類實體不當引用。我嘗試使用@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 + "]"; 
    } 

回答

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; 

更多信息

+0

謝謝你,我會檢查出來。我想知道JAXB有沒有很好的eclipselink參考。我剛剛看到@pace提到的地鐵引用,但並不確定是否有針對eclipselink實現的引用。 – grantk 2011-04-21 14:07:15

+0

我帶領的EclipseLink JAXB實現(莫西)和我的博客是很好的參考:http://bdoughan.blogspot.com/。 MOXy組件的網站是:http://www.eclipse.org/eclipselink/moxy.php – 2011-04-21 14:11:59