46486

JPA EclipseLink oneToMany Derived Ids Fail

Question:

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

<img alt="The database design" class="b-lazy" data-src="https://i.stack.imgur.com/Knxjv.png" data-original="https://i.stack.imgur.com/Knxjv.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

The entities:

<pre class="lang-java prettyprint-override">@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() { } } <pre class="lang-java prettyprint-override">@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(); } } <pre class="lang-java prettyprint-override">@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:

<pre class="lang-java prettyprint-override">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.

Answer1:

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(); }

Answer2:

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() { } }

Recommend

  • Order by in other table [closed]
  • Hibernate mappedby composite key
  • Problem removing entity with JPA
  • Combine instructions with a subquery in SQLite
  • How would you model data variables variance on common scheme? SQL
  • Pandas plotting two graphs on one scale
  • Fluent Nhibernate: Trying to create entity with composite key that is also the keys for two referenc
  • Need advice in designing tables in SQL-Server
  • JFreeChart BarChart - Category Markers
  • Regex: Match everything except backreference
  • PostgreSQL 9.1 timezones
  • ResponseBuilder is not working when used with entity object
  • Escaping single quotes in JDBC with MySql
  • CS1703: In Xamarin.Droid, should I use the .Net Standard windowsruntime.dll located in Mono.Framewor
  • Pythons argparse default value doesn't work
  • Why isn't my “Fizz Buzz” test in R working?
  • Python PIL to extract number from image
  • Cypher - matching two different possible paths and return both
  • How to plot large time series (thousands of administration times/doses of a medication)?
  • CodeIgniter URI Parameter is partially bypassing an “if” statement
  • opencv display image without x server
  • Owin Authentication and claims in asp.net how to access user data
  • How to make R's read_csv2() recognise the text characters properly
  • Scipy Leastsq Optional Output Variable (Mesg)
  • msbuild create itemgroup from property group
  • Android Activity.onWindowFocusChanged doesn't get called from within TabHost
  • Z3: Convert between FP and BitVector?
  • C: Incompatible pointer type initializing
  • Date Conversion from yyyy-mm-dd to dd-mm-yyyy
  • How to access EntityManager inside Entity class in EJB3
  • Repeat a vertical line on every page in Report Builder / SSRS
  • Getting last autonumber in access
  • Counter field in MS Access, how to generate?
  • Convert array of 8 bytes to signed long in C++
  • Alternatives to the OPTIONAL fallback SPARQL pattern?
  • Compare two NSDates in iPhone
  • Bitwise OR returns boolean when one of operands is nil
  • sending mail using smtp is too slow
  • costura.fody for a dll that references another dll
  • Binding checkboxes to object values in AngularJs