1

Model/Entity 1: PriceListItemTest.Java

package com.Pricing.Pricing_App.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonPropertyOrder({"pricingUOMCode","lineTypeCode","primaryPricingUOMFlag","priceListId","itemId","priceListItemId"})


@Entity
@Table(name = "QP_PRICE_LIST_ITEMS")
public class PriceListItemTest implements Serializable{

//  @Id
    @Column(name = "price_list_item_id")    
    private String priceListItemId;

    @Column(name = "pricing_uom_code")  
    private String pricingUOMCode; 

    @Column(name = "line_type_code")    
    private String lineTypeCode; 

    @Column(name = "primary_pricing_uom_flag")  
    private String primaryPricingUOMFlag;

    @Id
    @Column(name = "item_id")   
    private String itemId;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "item_id", referencedColumnName = "inventory_item_id")
//    @JoinColumn(name = "inventory_item_id", referencedColumnName = "item_id")
    private List<ItemDetailTest> itemDetailsTest;

    public List<ItemDetailTest> getItemDetailsTest() {
        return itemDetailsTest;
    }

    public void setItemDetailsTest(List<ItemDetailTest> itemDetailsTest) {
        this.itemDetailsTest = itemDetailsTest;
    }

    public String getPricingUOMCode() {
        return pricingUOMCode;
    }

    public void setPricingUOMCode(String pricingUOMCode) {
        this.pricingUOMCode = pricingUOMCode;
    }

    public String getLineTypeCode() {
        return lineTypeCode;
    }

    public void setLineTypeCode(String lineTypeCode) {
        this.lineTypeCode = lineTypeCode;
    }

    public String getPrimaryPricingUOMFlag() {
        return primaryPricingUOMFlag;
    }

    public void setPrimaryPricingUOMFlag(String primaryPricingUOMFlag) {
        this.primaryPricingUOMFlag = primaryPricingUOMFlag;
    }

    public String getItemId() {
        return itemId;
    }

    public void setItemId(String itemId) {
        this.itemId = itemId;
    }

    public String getPriceListItemId() {
        return priceListItemId;
    }

    public void setPriceListItemId(String priceListItemId) {
        this.priceListItemId = priceListItemId;
    }   
}

Model/Entity 2: ItemDetailTest.java

package com.Pricing.Pricing_App.model;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonPropertyOrder({"itemNumber","inventoryItemId","organizationId"})


@Entity
@Table(name = "egp_system_items_b")
public class ItemDetailTest implements Serializable {
    @Id
    @Column(name = "inventory_item_id") 
    private String inventoryItemId; 

    @Column(name = "item_number")   
    private String itemNumber; 

    @Column(name = "organization_id")   
    private String organizationId;

    public String getItemNumber() {
        return itemNumber;
    }

    public void setItemNumber(String itemNumber) {
        this.itemNumber = itemNumber;
    }

    public String getInventoryItemId() {
        return inventoryItemId;
    }

    public void setInventoryItemId(String inventoryItemId) {
        this.inventoryItemId = inventoryItemId;
    }

    public String getOrganizationId() {
        return organizationId;
    }

    public void setOrganizationId(String organizationId) {
        this.organizationId = organizationId;
    }
}

I am not able to start the local server and getting below error:

    Exception encountered during context initialization - cancelling refresh 
    attempt: org.springframework.beans.factory.BeanCreationException: Error 
    creating bean with name 'entityManagerFactory' defined in class path 
    resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class] 
   : Invocation of init method failed; nested exception is 
    org.hibernate.AnnotationException: Unable to map collection 
    com.Pricing.Pricing_App.model.PriceListItemTest.itemDetailsTest

I think there is some problem in mapping, Can some one help with it ? If I change the relation to OneToOne it is working fine. But the expectation is to make it onetomany

Manoj Kumar
  • 139
  • 1
  • 3
  • 12
  • The `@JoinColumn` represents a column in the ELEMENT table, and the "referencedColumnName" should be the column in the owner (e.g item_id). Your current specification is wrong ... shame your JPA provider doesnt seem to say that explicitly –  Oct 23 '18 at 10:30
  • Answer in the below link does not align with your comments https://stackoverflow.com/questions/11244569/what-is-referencedcolumnname-used-for-in-jpa – Manoj Kumar Oct 23 '18 at 12:50
  • Go consult any JPA docs, the `JoinColumn` defines the FK ... at the element side. http://www.datanucleus.org:15080/products/accessplatform_5_2/jpa/mapping.html#one_many_fk_uni which is of course also in the JPA spec. –  Oct 23 '18 at 13:58

2 Answers2

4

Look at your mapping. You are trying to map a FK in the element table.

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "item_id", referencedColumnName = "inventory_item_id")
//    @JoinColumn(name = "inventory_item_id", referencedColumnName = "item_id")
private List<ItemDetailTest> itemDetailsTest;

You have the "name" and "referencedColumnName" the wrong way around. Remove your current @JoinColumn and uncomment the other one, and also remove the referencedColumnName because you only have 1 PK field in the owner, hence that specification is the default (i.e just specify the "name" ... the name of the FK column in the element table). All of that is found in any decent JPA docs.

1

One to Many side:

@Entity
public class PriceListItem {
    @OneToMany(mappedBy = "listItem", cascade = ALL)
    private List<ItemDetail> itemDetails;
    // getters, setters, other fields
}

Many to One side:

public class ItemDetail {
    @ManyToOne
    private PriceListItem listItem;
    // getters, setters, other fields
}
Sasha Shpota
  • 9,436
  • 14
  • 75
  • 148
  • Omit the `@JoinColumn` and it gets a join table. Does the question ask for a join table rather than the FK it currently seemingly wants? –  Oct 23 '18 at 14:02
  • @BillyFrost I didn't quite get what you mean. It doesn't work for OP because he didn't configure the opposite mapping. – Sasha Shpota Oct 23 '18 at 14:12
  • A 1-N can be mapped using either a FK, or a join table. He put a join column, so he can have a FK. You removed it, so he gets a join table. You also forced the relation to be BIDIRECTIONAL, whereas he had UNIDIRECTIONAL (but incorrectly mapped the join column) –  Oct 23 '18 at 14:57