Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Updating non native foreign keys in chained JPA datasources

    Hi Isomorphic,

    I'm facing a few issues related to updating the foreign key in a bunch of chained datasources. Basically, I have 3 JPA domains (descriptions provided below). FOrderProducts and OrderProducts have a one to one relationship and OrderProducts and Products also have a one to one relationship.

    In the datasource that I've created, in case of a fetch operation I require Products.id using which I bind the products combo box optionDataSource in my list grid. However, in case the value of this combo box changes I need to update the value of OrderProducts.products (which is a foreign key to Products.id) but not Products.id.

    In order to do this I created a datasource like so:

    Code:
    <DataSource 
    	allowAdvancedCriteria="true"
    	dropExtraFields="true"
    	beanClassName="com.bmf.domain.FOrderProducts"
    	ID="FProducts"
    	entityName="com.bmf.domain.FOrderProducts"
    	serverType="jpa"
    >
    	<fields>
    		<field hidden="true" primaryKey="true" name="idOrderProducts" length="255" canEdit="false" required="false" type="sequence"></field>
    		<field name="currenciesByCurrency" foreignKey="Currencies.id"/>
    		<field name="products" includeFrom="OrderProducts.products" type="integer"/>
    		<field name="orderProducts" foreignKey="OrderProducts.id" hidden="true"/>		
    	</fields>
    </DataSource>
    Related OrderProducts datasource:

    Code:
    <DataSource 
    	allowAdvancedCriteria="true"
    	dropExtraFields="true"
    	beanClassName="com.bmf.domain.OrderProducts"
    	ID="OrderProducts"
    	entityName="com.bmf.domain.OrderProducts"
    	serverType="jpa"
    >
    	<fields>
    		<field hidden="true" primaryKey="true" name="id" length="255" canEdit="false" required="false" type="sequence"></field>
    		<field name="products" foreignKey="Products.id" />
    	</fields>
    </DataSource>
    The above DS definition with the includeFrom="OrderProducts.products" doesn't seem to work most likely because OrderProducts.products is not a simple type. The fetch operation throws an error and never returns.

    I therefore replaced the includeFrom with something like this: valueXPath="orderProducts.products.id". However, in this scenario the update operation tries to update Products.id and not OrderProducts.products. My intention is to try and update the intermediary field that connects OrderProducts with Products. This JPA representation of this column, however, is non native. How can I go about doing something like this?


    JPA domains for reference:

    Code:
    @Entity
    @Table(name = "f_order_products", catalog = "bmf_mar17", uniqueConstraints = @UniqueConstraint(columnNames = { "id_order_products",
    		"currency" }))
    public class FOrderProducts implements java.io.Serializable {
    
    	private long idOrderProducts;
    	private OrderProducts orderProducts;
    	private Currencies currenciesByBaseCurrency;
    	private Currencies currenciesByCurrency;
    	private fProductStatus fProductStatus;
    
    	public FOrderProducts() {
    	}
    
    	public FOrderProducts(OrderProducts orderProducts, Currencies currenciesByCurrency) {
    		this.orderProducts = orderProducts;
    		this.currenciesByCurrency = currenciesByCurrency;
    	}
    
    	public FOrderProducts(OrderProducts orderProducts, Currencies currenciesByBaseCurrency, Currencies currenciesByCurrency,
    			fProductStatus fProductStatus) {
    		this.orderProducts = orderProducts;
    		this.currenciesByBaseCurrency = currenciesByBaseCurrency;
    		this.currenciesByCurrency = currenciesByCurrency;
    		this.fProductStatus = fProductStatus;
    	}
    
    	@GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "orderProducts"))
    	@Id
    	@GeneratedValue(generator = "generator")
    	@Column(name = "id_order_products", unique = true, nullable = false)
    	public long getIdOrderProducts() {
    		return this.idOrderProducts;
    	}
    
    	public void setIdOrderProducts(long idOrderProducts) {
    		this.idOrderProducts = idOrderProducts;
    	}
    
    	@OneToOne(fetch = FetchType.LAZY)
    	@PrimaryKeyJoinColumn
    	public OrderProducts getOrderProducts() {
    		return this.orderProducts;
    	}
    
    	public void setOrderProducts(OrderProducts orderProducts) {
    		this.orderProducts = orderProducts;
    	}
    
    	@ManyToOne(fetch = FetchType.LAZY)
    	@JoinColumn(name = "base_Currency")
    	public Currencies getCurrenciesByBaseCurrency() {
    		return this.currenciesByBaseCurrency;
    	}
    
    	public void setCurrenciesByBaseCurrency(Currencies currenciesByBaseCurrency) {
    		this.currenciesByBaseCurrency = currenciesByBaseCurrency;
    	}
    
    	@ManyToOne(fetch = FetchType.LAZY)
    	@JoinColumn(name = "currency", nullable = false)
    	public Currencies getCurrenciesByCurrency() {
    		return this.currenciesByCurrency;
    	}
    
    	public void setCurrenciesByCurrency(Currencies currenciesByCurrency) {
    		this.currenciesByCurrency = currenciesByCurrency;
    	}
    
    	@OneToOne(fetch = FetchType.LAZY, mappedBy = "FOrderProducts", cascade = CascadeType.ALL)
    	public fProductStatus getfProductStatus() {
    		return this.fProductStatus;
    	}
    
    	public void setfProductStatus(fProductStatus fProductStatus) {
    		this.fProductStatus = fProductStatus;
    	}
    
    }
    Code:
    /**
     * OrderProducts generated by hbm2java
     */
    @Entity
    @Table(name = "order_products", catalog = "bmf_mar17")
    public class OrderProducts implements java.io.Serializable {
    
    	private Long id;
    	private StatusMaster statusMaster;
    	private Products products;
    	private Integer qty;
    	private Double tax;
    	private Double commission;
    	private Double discount;
    	private Double price;
    	private Date dateAdd;
    	private Date dateUpd;
    	private Set<CatCartItems> catCartItemses = new HashSet<CatCartItems>(0);
    	private FOrderProducts FOrderProducts;
    
    	public OrderProducts() {
    	}
    
    	public OrderProducts(StatusMaster statusMaster, Products products, Integer qty, Double tax, Double commission, Double discount,
    			Double price, Date dateAdd, Date dateUpd, Set<CatCartItems> catCartItemses, FOrderProducts FOrderProducts) {
    		this.statusMaster = statusMaster;
    		this.products = products;
    		this.qty = qty;
    		this.tax = tax;
    		this.commission = commission;
    		this.discount = discount;
    		this.price = price;
    		this.dateAdd = dateAdd;
    		this.dateUpd = dateUpd;
    		this.catCartItemses = catCartItemses;
    		this.FOrderProducts = FOrderProducts;
    	}
    
    	@Id
    	@GeneratedValue(strategy = IDENTITY)
    	@Column(name = "id", unique = true, nullable = false)
    	public Long getId() {
    		return this.id;
    	}
    
    	public void setId(Long id) {
    		this.id = id;
    	}
    
    	@ManyToOne(fetch = FetchType.LAZY)
    	@JoinColumn(name = "id_status_code")
    	public StatusMaster getStatusMaster() {
    		return this.statusMaster;
    	}
    
    	public void setStatusMaster(StatusMaster statusMaster) {
    		this.statusMaster = statusMaster;
    	}
    
    	@ManyToOne(fetch = FetchType.LAZY)
    	@JoinColumn(name = "id_product")
    	public Products getProducts() {
    		return this.products;
    	}
    
    	public void setProducts(Products products) {
    		this.products = products;
    	}
    
    	@Column(name = "qty")
    	public Integer getQty() {
    		return this.qty;
    	}
    
    	public void setQty(Integer qty) {
    		this.qty = qty;
    	}
    
    	@Column(name = "tax", precision = 22, scale = 0)
    	public Double getTax() {
    		return this.tax;
    	}
    
    	public void setTax(Double tax) {
    		this.tax = tax;
    	}
    
    	@Column(name = "commission", precision = 22, scale = 0)
    	public Double getCommission() {
    		return this.commission;
    	}
    
    	public void setCommission(Double commission) {
    		this.commission = commission;
    	}
    
    	@Column(name = "discount", precision = 22, scale = 0)
    	public Double getDiscount() {
    		return this.discount;
    	}
    
    	public void setDiscount(Double discount) {
    		this.discount = discount;
    	}
    
    	@Column(name = "price", precision = 22, scale = 0)
    	public Double getPrice() {
    		return this.price;
    	}
    
    	public void setPrice(Double price) {
    		this.price = price;
    	}
    
    	@Temporal(TemporalType.TIMESTAMP)
    	@Column(name = "date_add", length = 19)
    	public Date getDateAdd() {
    		return this.dateAdd;
    	}
    
    	public void setDateAdd(Date dateAdd) {
    		this.dateAdd = dateAdd;
    	}
    
    	@Temporal(TemporalType.TIMESTAMP)
    	@Column(name = "date_upd", length = 19)
    	public Date getDateUpd() {
    		return this.dateUpd;
    	}
    
    	public void setDateUpd(Date dateUpd) {
    		this.dateUpd = dateUpd;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "orderProducts")
    	public Set<CatCartItems> getCatCartItemses() {
    		return this.catCartItemses;
    	}
    
    	public void setCatCartItemses(Set<CatCartItems> catCartItemses) {
    		this.catCartItemses = catCartItemses;
    	}
    
    	@OneToOne(fetch = FetchType.LAZY, mappedBy = "orderProducts", cascade = CascadeType.ALL)
    	public FOrderProducts getFOrderProducts() {
    		return this.FOrderProducts;
    	}
    
    	public void setFOrderProducts(FOrderProducts FOrderProducts) {
    		this.FOrderProducts = FOrderProducts;
    	}
    
    }
    Code:
    @Entity
    @Table(name = "products", catalog = "bmf_mar17", uniqueConstraints = @UniqueConstraint(columnNames = "code"))
    public class Products implements java.io.Serializable {
    
    	private Long id;
    	private Categories categories;
    	private String code;
    	private String description;
    	private Boolean isActive;
    	private String imagePath;
    	private String detailsLink;
    	private Set<LocationsProducts> locationsProductses = new HashSet<LocationsProducts>(
    			0);
    	private Set<RateAlerts> rateAlertses = new HashSet<RateAlerts>(0);
    	private Set<OrderProducts> orderProductses = new HashSet<OrderProducts>(0);
    	private Set<InsurancePremium> insurancePremiums = new HashSet<InsurancePremium>(
    			0);
    	private Set<ProductCurrencyDirection> productCurrencyDirections = new HashSet<ProductCurrencyDirection>(
    			0);
    	private Set<ModesOfTransfers> modesOfTransferses = new HashSet<ModesOfTransfers>(
    			0);
    	private Set<MinDenominations> minDenominationses = new HashSet<MinDenominations>(
    			0);
    	private Set<TravelInsuranceDeals> travelInsuranceDealses = new HashSet<TravelInsuranceDeals>(
    			0);
    	private Set<InsuranceProductDetails> insuranceProductDetailses = new HashSet<InsuranceProductDetails>(
    			0);
    	private Set<InsuranceCoverage> insuranceCoverages = new HashSet<InsuranceCoverage>(
    			0);
    	private Set<ForexItem> forexItems = new HashSet<ForexItem>(0);
    
    	public Products() {
    	}
    
    	public Products(Categories categories, String code, String description,
    			Boolean isActive, String imagePath, String detailsLink,
    			Set<LocationsProducts> locationsProductses,
    			Set<RateAlerts> rateAlertses, Set<OrderProducts> orderProductses,
    			Set<InsurancePremium> insurancePremiums,
    			Set<ProductCurrencyDirection> productCurrencyDirections,
    			Set<ModesOfTransfers> modesOfTransferses,
    			Set<MinDenominations> minDenominationses,
    			Set<TravelInsuranceDeals> travelInsuranceDealses,
    			Set<InsuranceProductDetails> insuranceProductDetailses,
    			Set<InsuranceCoverage> insuranceCoverages, Set<ForexItem> forexItems) {
    		this.categories = categories;
    		this.code = code;
    		this.description = description;
    		this.isActive = isActive;
    		this.imagePath = imagePath;
    		this.detailsLink = detailsLink;
    		this.locationsProductses = locationsProductses;
    		this.rateAlertses = rateAlertses;
    		this.orderProductses = orderProductses;
    		this.insurancePremiums = insurancePremiums;
    		this.productCurrencyDirections = productCurrencyDirections;
    		this.modesOfTransferses = modesOfTransferses;
    		this.minDenominationses = minDenominationses;
    		this.travelInsuranceDealses = travelInsuranceDealses;
    		this.insuranceProductDetailses = insuranceProductDetailses;
    		this.insuranceCoverages = insuranceCoverages;
    		this.forexItems = forexItems;
    	}
    
    	@Id
    	@GeneratedValue(strategy = IDENTITY)
    	@Column(name = "id", unique = true, nullable = false)
    	public Long getId() {
    		return this.id;
    	}
    
    	public void setId(Long id) {
    		this.id = id;
    	}
    
    	@ManyToOne(fetch = FetchType.LAZY)
    	@JoinColumn(name = "id_category")
    	public Categories getCategories() {
    		return this.categories;
    	}
    
    	public void setCategories(Categories categories) {
    		this.categories = categories;
    	}
    
    	@Column(name = "code", unique = true, length = 250)
    	public String getCode() {
    		return this.code;
    	}
    
    	public void setCode(String code) {
    		this.code = code;
    	}
    
    	@Column(name = "description")
    	public String getDescription() {
    		return this.description;
    	}
    
    	public void setDescription(String description) {
    		this.description = description;
    	}
    
    	@Column(name = "is_active")
    	public Boolean getIsActive() {
    		return this.isActive;
    	}
    
    	public void setIsActive(Boolean isActive) {
    		this.isActive = isActive;
    	}
    
    	@Column(name = "image_path")
    	public String getImagePath() {
    		return this.imagePath;
    	}
    
    	public void setImagePath(String imagePath) {
    		this.imagePath = imagePath;
    	}
    
    	@Column(name = "details_link")
    	public String getDetailsLink() {
    		return this.detailsLink;
    	}
    
    	public void setDetailsLink(String detailsLink) {
    		this.detailsLink = detailsLink;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<LocationsProducts> getLocationsProductses() {
    		return this.locationsProductses;
    	}
    
    	public void setLocationsProductses(
    			Set<LocationsProducts> locationsProductses) {
    		this.locationsProductses = locationsProductses;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<RateAlerts> getRateAlertses() {
    		return this.rateAlertses;
    	}
    
    	public void setRateAlertses(Set<RateAlerts> rateAlertses) {
    		this.rateAlertses = rateAlertses;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<OrderProducts> getOrderProductses() {
    		return this.orderProductses;
    	}
    
    	public void setOrderProductses(Set<OrderProducts> orderProductses) {
    		this.orderProductses = orderProductses;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<InsurancePremium> getInsurancePremiums() {
    		return this.insurancePremiums;
    	}
    
    	public void setInsurancePremiums(Set<InsurancePremium> insurancePremiums) {
    		this.insurancePremiums = insurancePremiums;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<ProductCurrencyDirection> getProductCurrencyDirections() {
    		return this.productCurrencyDirections;
    	}
    
    	public void setProductCurrencyDirections(
    			Set<ProductCurrencyDirection> productCurrencyDirections) {
    		this.productCurrencyDirections = productCurrencyDirections;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<ModesOfTransfers> getModesOfTransferses() {
    		return this.modesOfTransferses;
    	}
    
    	public void setModesOfTransferses(Set<ModesOfTransfers> modesOfTransferses) {
    		this.modesOfTransferses = modesOfTransferses;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<MinDenominations> getMinDenominationses() {
    		return this.minDenominationses;
    	}
    
    	public void setMinDenominationses(Set<MinDenominations> minDenominationses) {
    		this.minDenominationses = minDenominationses;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<TravelInsuranceDeals> getTravelInsuranceDealses() {
    		return this.travelInsuranceDealses;
    	}
    
    	public void setTravelInsuranceDealses(
    			Set<TravelInsuranceDeals> travelInsuranceDealses) {
    		this.travelInsuranceDealses = travelInsuranceDealses;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<InsuranceProductDetails> getInsuranceProductDetailses() {
    		return this.insuranceProductDetailses;
    	}
    
    	public void setInsuranceProductDetailses(
    			Set<InsuranceProductDetails> insuranceProductDetailses) {
    		this.insuranceProductDetailses = insuranceProductDetailses;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<InsuranceCoverage> getInsuranceCoverages() {
    		return this.insuranceCoverages;
    	}
    
    	public void setInsuranceCoverages(Set<InsuranceCoverage> insuranceCoverages) {
    		this.insuranceCoverages = insuranceCoverages;
    	}
    
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "products")
    	public Set<ForexItem> getForexItems() {
    		return this.forexItems;
    	}
    
    	public void setForexItems(Set<ForexItem> forexItems) {
    		this.forexItems = forexItems;
    	}
    
    }
    SmartClient Version: v9.1p_2014-09-01/EVAL Deployment (expires 2014.10.31_04.45.35) Licensed to: Isomorphic Software (#ISC_EVAL_NIGHTLY)
    Last edited by nitrojin; 26 Sep 2014, 12:48. Reason: Forgot basic versioning info

    #2
    We need more information. Could you provide the following:
    - definition of the Products.ds.xml (I suppose this should exist);
    - complete server log for the fetch call (which one "throws an error and never returns");
    - the source code of client (javascript or SmartGWT), if possible without unrelated code;
    - the description of what exactly should be done in UI to produce the error and what your expectations are;

    Please make sure that all code you provide is up to date and is exactly one you are getting the error with.

    Comment


      #3
      Hi Isomorphic,

      Thanks for the reply. I managed to figure this out for the most part. Basically since I needed to refer to different columns when fetching and updating the same field, I ended up using both valueXPath and valueWriteXPath. I still, however, need to use a DMI to convert the integer primary key value passed in from the client and retrieve the Products object from it. Is there any way to avoid this step and do it all without a DMI?

      Comment


        #4
        I'm not sure why you would need DMI to manually transform primary key into an Entity. Please check link below describing how to use JPA relations at data source level:
        http://www.smartclient.com/docs/9.1/a/b/c/go.html#group..jpaHibernateRelations

        If you still have problems, please describe them in more detailed way with data source configs, code samples and server logs.

        Comment

        Working...
        X