1

I am trying to apply One to One relationship between orders and invoice table. But I am getting following error.

    run:
[EL Info]: 2014-04-19 01:52:07.791--ServerSession(287170778)--EclipseLink, version: Eclipse Persistence Services - 2.2.0.v20110202-r8913
[EL Severe]: 2014-04-19 01:52:08.256--ServerSession(287170778)--Local Exception Stack: 
Exception [EclipseLink-0] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-48] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [ORDER_INVOICE.ORDER_ID].  Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[order]
Descriptor: RelationalDescriptor(entity.Invoice --> [DatabaseTable(ORDER_INVOICE)])

Runtime Exceptions: 
---------------------------------------------------------

    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:476)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:407)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:680)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:628)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:233)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:394)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:185)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:242)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:230)
    at test.OneToOneTest.main(OneToOneTest.java:14)

Descriptor Exceptions: 
---------------------------------------------------------


Local Exception Stack: 
Exception [EclipseLink-48] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [ORDER_INVOICE.ORDER_ID].  Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[order]
Descriptor: RelationalDescriptor(entity.Invoice --> [DatabaseTable(ORDER_INVOICE)])
    at org.eclipse.persistence.exceptions.DescriptorException.multipleWriteMappingsForField(DescriptorException.java:1003)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.initialize(ObjectBuilder.java:2839)
    at org.eclipse.persistence.descriptors.ClassDescriptor.initialize(ClassDescriptor.java:2857)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:453)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:407)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:680)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:628)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:233)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:394)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:185)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:242)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:230)
    at test.OneToOneTest.main(OneToOneTest.java:14)

Runtime Exceptions: 
---------------------------------------------------------

[EL Severe]: 2014-04-19 01:52:08.26--ServerSession(287170778)--Local Exception Stack: 
Exception [EclipseLink-0] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-48] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [ORDER_INVOICE.ORDER_ID].  Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[order]
Descriptor: RelationalDescriptor(entity.Invoice --> [DatabaseTable(ORDER_INVOICE)])

Runtime Exceptions: 
---------------------------------------------------------

    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:476)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:407)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:680)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:628)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:233)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:394)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:185)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:242)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:230)
    at test.OneToOneTest.main(OneToOneTest.java:14)

Descriptor Exceptions: 
---------------------------------------------------------


Local Exception Stack: 
Exception [EclipseLink-48] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [ORDER_INVOICE.ORDER_ID].  Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[order]
Descriptor: RelationalDescriptor(entity.Invoice --> [DatabaseTable(ORDER_INVOICE)])
    at org.eclipse.persistence.exceptions.DescriptorException.multipleWriteMappingsForField(DescriptorException.java:1003)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.initialize(ObjectBuilder.java:2839)
    at org.eclipse.persistence.descriptors.ClassDescriptor.initialize(ClassDescriptor.java:2857)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:453)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:407)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:680)
Exception in thread "main" javax.persistence.PersistenceException: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.IntegrityException
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:628)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:233)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:394)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:185)
Descriptor Exceptions: 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:242)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:230)
    at test.OneToOneTest.main(OneToOneTest.java:14)

Runtime Exceptions: 
---------------------------------------------------------

---------------------------------------------------------

Exception [EclipseLink-48] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [ORDER_INVOICE.ORDER_ID].  Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[order]
Descriptor: RelationalDescriptor(entity.Invoice --> [DatabaseTable(ORDER_INVOICE)])

Runtime Exceptions: 
---------------------------------------------------------

    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:422)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:185)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:242)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:230)
    at test.OneToOneTest.main(OneToOneTest.java:14)
Caused by: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-48] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [ORDER_INVOICE.ORDER_ID].  Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[order]
Descriptor: RelationalDescriptor(entity.Invoice --> [DatabaseTable(ORDER_INVOICE)])

Runtime Exceptions: 
---------------------------------------------------------

    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:476)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:407)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:680)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:628)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:233)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:394)
    ... 4 more
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)

Entity Class: Order ( An order must have an invoice)

    package entity;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.MapKey;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;

/*
 * Order Entity - maps to ORDERS table
 */

@Entity(name = "ORDER") 
public class Order {

    @Id 
    @Column(name = "ORDER_ID", nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long orderId;

    @Column(name = "CUST_ID")
    private long custId;

    @Column(name = "TOTAL_PRICE", precision = 2)
    private double totPrice;

    @Column(name = "OREDER_DESC")
    private String orderDesc;

    @Column(name = "ORDER_DATE") 
         @Temporal(TemporalType.TIMESTAMP)
    private Date orderDt;   

    @OneToOne(optional=false,cascade=CascadeType.ALL, mappedBy="order",targetEntity=Invoice.class)
    private Invoice invoice;

    /*@ManyToOne(optional=false)
    @JoinColumn(name="CUST_ID",referencedColumnName="CUST_ID")
    private Customer customer;


    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(name="ORDER_DETAIL",
            joinColumns=
                @JoinColumn(name="ORDER_ID", referencedColumnName="ORDER_ID"),
            inverseJoinColumns=
                @JoinColumn(name="PROD_ID", referencedColumnName="PROD_ID")
    )*/
    //private List<Product> productList;


    @Column(name = "LAST_UPDATED_TIME")
         @Temporal(TemporalType.TIMESTAMP)
    private Date updatedTime;


    public String toString() {
       StringBuffer sb = new StringBuffer();
       sb.append("orderId : " + orderId);
       sb.append("   custId : " + custId);
       sb.append("   totPrice : " + totPrice);
       sb.append("   orderDesc : " + orderDesc);
       sb.append("   orderDt : " + orderDt);
       //sb.append("   invoice : " + invoice);
       //sb.append("   products : " + productList);
       return sb.toString();
   }

    public long getCustId() {
        return custId;
    }

    public void setCustId(long custId) {
        this.custId = custId;
    }

    public String getOrderDesc() {
        return orderDesc;
    }

    public void setOrderDesc(String orderDesc) {
        this.orderDesc = orderDesc;
    }

    public Date getOrderDt() {
        return orderDt;
    }

    public void setOrderDt(Date orderDt) {
        this.orderDt = orderDt;
    }

    public long getOrderId() {
        return orderId;
    }

    public void setOrderId(long orderId) {
        this.orderId = orderId;
    }

    public double getTotPrice() {
        return totPrice;
    }

    public void setTotPrice(double totPrice) {
        this.totPrice = totPrice;
    }

    public Date getUpdatedTime() {
        return updatedTime;
    }

    public void setUpdatedTime(Date updatedTime) {
        this.updatedTime = updatedTime;
    }

    public Invoice getInvoice() {
        return invoice;
    }

    public void setInvoice(Invoice invoice) {
        this.invoice = invoice;
    }

    /*public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }*/

    /*public List<Product> getProductList() {
        return productList;
    }

    public void setProductList(List<Product> productList) {
        this.productList = productList;
    }*/



}

Entity Class: Invoice

   package entity;

import java.util.Date;

import javax.persistence.*;

/*
 * INVOICE Entity - maps to ORDER_INVOICE table
 */
@Entity(name = "ORDER_INVOICE") 
public class Invoice {

    @Id //signifies the primary key
    @Column(name = "INVOICE_ID", nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long invoiceId;

    //@Column(name = "ORDER_ID")
    //sprivate long orderId;

    @Column(name = "AMOUNT_DUE", precision = 2)
    private double amountDue;

    @Column(name = "DATE_RAISED") 
          @Temporal(TemporalType.TIMESTAMP)
    private Date orderRaisedDt;

    @Column(name = "DATE_SETTLED") 
          @Temporal(TemporalType.TIMESTAMP)
    private Date orderSettledDt;

    @Column(name = "DATE_CANCELLED")
          @Temporal(TemporalType.TIMESTAMP)
    private Date orderCancelledDt;


    @Column(name = "LAST_UPDATED_TIME")
          @Temporal(TemporalType.TIMESTAMP)
    private Date updatedTime;

    @OneToOne(optional=false)
    @JoinColumn(name = "ORDER_ID") 
    private Order order;

    public String toString() {
       StringBuffer sb = new StringBuffer();
      // sb.append("orderId : " + orderId);
       sb.append("   invoiceId : " + invoiceId);
       sb.append("   amtDue : " + amountDue);
       sb.append("   orderRaisedDt : " + orderRaisedDt);
       sb.append("   orderSettledDt : " + orderSettledDt);
       sb.append("   orderCancelledDt : " + orderCancelledDt);
       sb.append("   updatedTime : " + updatedTime);
       return sb.toString();
   }


    public Date getUpdatedTime() {
        return updatedTime;
    }

    public void setUpdatedTime(Date updatedTime) {
        this.updatedTime = updatedTime;
    }


    public long getInvoiceId() {
        return invoiceId;
    }


    public void setInvoiceId(long invoiceId) {
        this.invoiceId = invoiceId;
    }


    public Date getOrderRaisedDt() {
        return orderRaisedDt;
    }


    public void setOrderRaisedDt(Date orderRaisedDt) {
        this.orderRaisedDt = orderRaisedDt;
    }


    public Order getOrder() {
        return order;
    }


    public void setOrder(Order order) {
        this.order = order;
    }


    /*public long getOrderId() {
        return orderId;
    }


    public void setOrderId(long orderId) {
        this.orderId = orderId;
    }*/


    public double getAmountDue() {
        return amountDue;
    }


    public void setAmountDue(double amountDue) {
        this.amountDue = amountDue;
    }


    public Date getOrderCancelledDt() {
        return orderCancelledDt;
    }


    public void setOrderCancelledDt(Date orderCancelledDt) {
        this.orderCancelledDt = orderCancelledDt;
    }


    public Date getOrderSettledDt() {
        return orderSettledDt;
    }


    public void setOrderSettledDt(Date orderSettledDt) {
        this.orderSettledDt = orderSettledDt;
    }
}

Main Class:

 package test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import entity.Order;

public class OneToOneTest {

    public static void main(String[] args) {
        EntityManagerFactory entityManagerFactory =  Persistence.createEntityManagerFactory("TESTJPAPU");

        EntityManager em = entityManagerFactory.createEntityManager();

        Order order = em.find(Order.class, 111);
        em.close();
        entityManagerFactory.close();
        System.out.println("order : " + order);

    }
}

Persistence.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="TESTJPAPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>entity.Customer</class>
        <class>entity.Address</class>    
        <class>entity.OnlineCustomer</class>
        <class>entity.CustomerSingle</class>  
        <class>entity.OnlineCustomerJoined</class>
        <class>entity.CustomerJoined</class>
        <class>entity.OnlineCustomerTable</class>
        <class>entity.CustomerTable</class>
        <class>entity.Order</class>
        <class>entity.Invoice</class>

    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/CUSTOMERJPA?zeroDateTimeBehavior=convertToNull"/>
      <property name="javax.persistence.jdbc.password" value=""/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.user" value="root"/>

      <property name="eclipselink.create-ddl-jdbc-file-name" value="createDDL_ddlGeneration.jdbc"/> 
      <property name="eclipselink.drop-ddl-jdbc-file-name" value="dropDDL_ddlGeneration.jdbc"/> 
      <property name="eclipselink.ddl-generation.output-mode" value="both"/>
    </properties>
  </persistence-unit>
</persistence>
Sumaira Rounaq
  • 49
  • 1
  • 3
  • 6
  • Please, visit [multiple-writable-mappings-exception-in-eclipselink](http://stackoverflow.com/questions/7952115/multiple-writable-mappings-exception-in-eclipselink) and see answer from klonq – Mikro Koder Mar 16 '17 at 20:39

1 Answers1

2

From the above code I can see that one-to-one mapping between Invoice and Order entities has been defined properly. The root-cause of the exception may be related to the obsolete database schema that was created with an old entity model and it is still used by the application.

Try to add the following property to persistence.xml:

<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>

It will force recreating the database schema from the current entity model.

wypieprz
  • 7,981
  • 4
  • 43
  • 46