Search code examples
databasejpajpa-2.0entity-relationship

How to implement manually JPA relation OneToMany


I am using JPA annotations and when i have relation OneToMany - ManyToOne, when i see my entity in the ManyToOne, the joinColumn is always with null value.

Next i will show my example, i have Product:

  @Entity
  @Table(name = "PC_PRODUCT")

  public class Product extends LaunchEntity {

  private static final long serialVersionUID = 1L;

  @XmlElement(name = "Product_Name", required = true)
  protected String productName;

  @XmlElement(name = "Product_Description")
  protected String productDescription;

  @XmlElement(name = "Product_To_Charge")
  @OneToMany(mappedBy = "product", cascade=CascadeType.MERGE)
  protected List<ChargeRelation> productToCharge;

And, this is my ChargeRelation class:

@Entity
@Table(name="PC_CHARGE_RELATION")
public class ChargeRelation
    extends RelationEntity
{

    private static final long serialVersionUID = 1L;

    @XmlElement(name = "Charge", required = true)
    @OneToOne(cascade = CascadeType.MERGE)
    protected Charge charge;

    @XmlTransient
    @ManyToOne(cascade=CascadeType.MERGE)
    @JoinColumn(name="PRODUCT_ID")
    protected Product product;

I am reading a xml file, convert data for a string, make unmarshall for my root object and persist this object.

The problem is when i found a charge relation in my string, the values are inserted on the charge relation table but the column with the product_id is always null.

I have all setters and getters defined. How i can force this to make the manual insert? thanks


Solution

  • Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.

    EclipseLink JAXB (MOXy) has an extension called @XmlInverseReference that allows you to map the back-pointer.

    Product

    @Entity
    @Table(name = "PC_PRODUCT")
    public class Product extends LaunchEntity {
    
        @XmlElement(name = "Product_To_Charge")
        @OneToMany(mappedBy = "product", cascade=CascadeType.MERGE)
        protected List<ChargeRelation> productToCharge;
    
    }
    

    ChargeRelation

    The @XmlInverseReference annotation is used where you previously had @XmlTransient. @XmlInverseReference acts like @XmlTransient during the marshal operation, and will populate the back-pointer during an unmarshal operation.

    @Entity
    @Table(name="PC_CHARGE_RELATION")
    public class ChargeRelation extends RelationEntity {
    
        @XmlInverseReference(mappedBy = "productToCharge")
        @ManyToOne(cascade=CascadeType.MERGE)
        @JoinColumn(name="PRODUCT_ID")
        protected Product product;
    }
    

    For More Information