JAXB Unmarshalling для сущностей ошибка - PullRequest
2 голосов
/ 21 апреля 2011

У меня проблема с отменой сортировки потока XML для сущностей.Мои внешние ключи никогда не устанавливаются на объект с правильным первичным ключом, они просто устанавливаются на объект emtpy.

Класс с внешними ключами называется ProductBase.Он имеет ссылку на BrandData (поле 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 = (объект brandData каждое поле null) p1.categories = (объект Categories каждое поле null)p1.ts = (объект Date со значением 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 + "]";
    }

1 Ответ

2 голосов
/ 21 апреля 2011

Для этого варианта использования вам понадобится 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;

Для получения дополнительной информации

...