JPA EclipseLink oneToMany Derived Ids Fail

允我心安 提交于 2020-01-07 07:40:06

问题


Hello I'm trying to make an example of persistence of a OneToMany relationship in which I get the following error:

Exception Description: Invalid composite primary key specification. The names of the primary key fields or properties in the primary key class [entitys.OrderItemPK] and those of the entity bean class [class entitys.OrderItem] must correspond and their types must be the same. Also, ensure that you have specified ID elements for the corresponding attributes in XML and/or an @Id on the corresponding fields or properties of the entity class.

Note: I'm using EclipseLink and MySQL DB

The entities:

@Entity
public class CustomerOrder implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "idOrder")
    private Integer idOrder;

    @Basic(optional = false)
    @Column(name = "orderText")
    private String orderText;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "customerOrder")
    private Collection<OrderItem> orderItemCollection;

    public CustomerOrder() {
    }
}
@Entity
@IdClass(OrderItemPK.class)
public class OrderItem implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected OrderItemPK orderItemPK;

    @Basic(optional = false)
    @Column(name = "itemDesc")
    private String itemDesc;

@Id
@ManyToOne(optional = false)    
@JoinColumns({
    @JoinColumn(name="idOrder", referencedColumnName="idOrder"),
    @JoinColumn(name="ItemNumber", referencedColumnName="ItemNumber")
})      
//@JoinColumn(name = "idOrder", referencedColumnName = "idOrder", insertable = false, updatable = false)
private CustomerOrder customerOrder;
    private CustomerOrder customerOrder;

    public OrderItem() {
        this.orderItemPK = new OrderItemPK();
   }
}
@Embeddable
public class OrderItemPK implements Serializable {
    @Basic(optional = false)
    @Column(name = "idOrder")
    private int idOrder;

    @Basic(optional = false)
    @Column(name = "itemNumber")
    private int itemNumber;

    public OrderItemPK() {
    }
}

The test Source:

public static void main(String[] args) {
    factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    EntityManager em = factory.createEntityManager();

    em.getTransaction().begin();

    // Fill the items fileds
    OrderItem item = new OrderItem();
    item.setItemDesc("Item Text");

    // Fill the orders fields
    CustomerOrder order = new CustomerOrder();
    order.setOrderText("Order text");

    // Fill the relationship fields
    order.getOrderItemCollection().add(item);
    item.setCustomerOrder(order);        

    em.persist(order);
    em.getTransaction().commit();
}

I have no idea what I'm doing wrong, any suggestions are welcome.


回答1:


Well i managed to solve the problem by removing idClass annotation and adding the @MapId

heres the final code:

@Entity
@Table(name = "Orders")
public class CustomerOrder implements Serializable {
  private static final long serialVersionUID = 1L;
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Basic(optional = false)
  @Column(name = "idOrder")
  private Integer idOrder;
  @Basic(optional = false)
  @Column(name = "orderText")
  private String orderText;     

 @OneToMany(mappedBy = "customerOrder", cascade = CascadeType.ALL)
 private Collection<OrderItem> orderItemCollection;

 public CustomerOrder() {
 }

@Entity
@Table(name = "OrdersItems")
public class OrderItem implements Serializable {

  private static final long serialVersionUID = 1L;
  @EmbeddedId
  protected OrderItemPK orderItemPK;
  @Basic(optional = false)

  @Column(name = "itemDesc")
  private String itemDesc;

  @MapsId("idOrder")    
  @ManyToOne(optional = false)    
  @JoinColumn(name = "idOrder", referencedColumnName = "idOrder", nullable = false)    
  private CustomerOrder customerOrder;

  public OrderItem() {
    this.orderItemPK = new OrderItemPK();
  }

@Embeddable
public class OrderItemPK implements Serializable {
  @Basic(optional = false)
  @Column(name = "idOrder")
  private int idOrder;
  @Basic(optional = false)
  @Column(name = "itemNumber")
  private int itemNumber;

  public OrderItemPK() {
  }

public static void main(String[] args) {

    factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    EntityManager em = factory.createEntityManager();

    em.getTransaction().begin();

    // Fill the order item
    OrderItem item = new OrderItem();
    item.getOrderItemPK().setItemNumber(1);
    item.setItemDesc("Product Name");

    // Fill the order
    CustomerOrder order = new CustomerOrder();
    order.setOrderText("Testing");

    // Create relationship
    order.getOrderItemCollection().add(item);
    item.setCustomerOrder(order);

    // Persist
    em.persist(order);
    em.getTransaction().commit();        
}

But i can't get it work with IdClass, here's the source

@Embeddable
public class OrderItemPK implements Serializable {

  @Basic(optional = false)
  @Column(name = "idOrder")
  private Integer idOrder;

  @Basic(optional = false)
  @Column(name = "ItemNumber")
  private Integer itemNumber;

  public OrderItemPK() {
  }

@Entity
@IdClass(OrderItemPK.class)
public class OrderItem implements Serializable {
   private static final long serialVersionUID = 1L;

   @Id
   @Column(name = "itemNumber")
   private Integer itemNumber;

   @Basic(optional = false)
   @Column(name = "itemDesc")
   private String itemDesc;

   @MapsId("idOrder")    
   @ManyToOne(optional = false)    
   @JoinColumn(name = "idOrder", referencedColumnName = "idOrder", nullable = false) 
   private CustomerOrder customerOrder;

   public OrderItem() {
   }

  @Entity
  public class CustomerOrder implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "idOrder")
    private Integer idOrder;

    @Basic(optional = false)
    @Column(name = "OrderText")
    private String orderText;

    @OneToMany(mappedBy = "customerOrder", cascade = CascadeType.ALL)
    private Collection<OrderItem> orderItemCollection;

    public CustomerOrder() {
        this.orderItemCollection = new ArrayList();
    }



回答2:


Use MapsId in OrderItem:

@Entity
public class OrderItem implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected OrderItemPK orderItemPK;

    @Basic(optional = false)
    @Column(name = "itemDesc")
    private String itemDesc;

    @MapsId("idOrder")
    @ManyToOne(optional = false)       
    @JoinColumn(name = "idOrder", referencedColumnName = "idOrder")
    private CustomerOrder customerOrder;
}

An alternative is to remove the embedded id and use an ID class:

@Entity
@IdClass(OrderItemPK.class)
public class OrderItem implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "itemNumber")
    private int itemNumber;


    @Basic(optional = false)
    @Column(name = "itemDesc")
    private String itemDesc;

    @Id
    @ManyToOne(optional = false)       
    @JoinColumn(name = "idOrder", referencedColumnName = "idOrder")
    private CustomerOrder customerOrder;
}

public class OrderItemPK implements Serializable {
    //name of the relation in the entity, but same type as the CustomerOrder PK.
    int customerOrder;

    int itemNumber;

    public OrderItemPK() {
    }
}


来源:https://stackoverflow.com/questions/29012099/jpa-eclipselink-onetomany-derived-ids-fail

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!