Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] OneToMany does not populate Foreign Key or null foreign key

Thank you Chris,

Your recommendation to include a basic mapping for field codigo_upc_hijo
works fine.  I only need to set the field to the foreing key value before
the persist operation.

Here is the mapping:

@Entity
@Table(name = "test_hijo")
@NamedQueries({@NamedQuery(name = "TestHijo.findAll", query = "SELECT t FROM
TestHijo t")})
public class TestHijo implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected TestHijoPK testHijoPK;
    @Basic(optional = false)
    @Column(name = "unidad_medida")
    private String unidadMedida;
    @Basic(optional = false)
    @Column(name = "codigo_upc_hijo")
    private String codigoUpcHijo;
    @JoinColumns({@JoinColumn(name = "codigo_upc_hijo", referencedColumnName
= "codigo_upc", nullable=false), @JoinColumn(name = "id_empresa",
referencedColumnName = "id_empresa", insertable = false, updatable =
false)})
    @ManyToOne(optional = false)
    private TestPadre testPadre;


In order to document/close this case, I want to add that if I set the
mappings for both fields insertable/updatable=true, EclipseLink 1.2 will
generate the following error:

	
Exception [EclipseLink-0] (Eclipse Persistence Services -
1.2.0.v20091016-r5565):
org.eclipse.persistence.exceptions.IntegrityException Descriptor Exceptions:
--------------------------------------------------------- Exception
[EclipseLink-48] (Eclipse Persistence Services - 1.2.0.v20091016-r5565):
org.eclipse.persistence.exceptions.DescriptorException Exception
Description: Multiple writable mappings exist for the field
[test_hijo.id_empresa]. Only one may be defined as writable, all others must
be specified read-only. Mapping:
org.eclipse.persistence.mappings.OneToOneMapping[testPadre] Descriptor:
RelationalDescriptor(com.mobilges.server.lib.model.inventory.TestHijo -->
[DatabaseTable(test_hijo)]) Runtime Exceptions: 

So, it is necessary to use the suggested workaround meanwhile I migrate to
EclipseLink 2.0

Regards
Antonio




christopher delahunt wrote:
> 
> Hello,
> 
> The mapping has one field (id_empresa) marked as 
> insertable/updatable=false, which causes EclipseLink to mark the mapping 
> as read-only due to bug 280436 and fixed in the 2.0 EclipseLink release.
> 
> If you cannot upgrade, the workaround is to make the entire mapping 
> writable or to add a basic mapping for the codigo_upc_hijo field.
> 
> Best Regards,
> Chris
> 
> AntonioJSG wrote:
>> Thank you James,
>>
>> I did enable FINE logging, there is no previous insert for TestPadre.
>> Based on your suggestion, I did change the update code to insert
>> TestPadre
>> first and then try to Merge TestHijo.
>>
>> These are the sql generated statements
>>
>> 	
>> INSERT INTO test_padre (nombre, id_empresa, codigo_upc) VALUES (?, ?, ?)
>> bind => [nombre de Test, se001, 200]
>> 	
>> INSERT INTO test_hijo (unidad_medida, id_empresa, codigo_sku) VALUES (?,
>> ?,
>> ?) bind => [unidad Medida, se001, 200]
>>
>> The error
>>
>> Exception [EclipseLink-4002] (Eclipse Persistence Services -
>> 1.2.0.v20091016-r5565):
>> org.eclipse.persistence.exceptions.DatabaseException
>> Internal Exception: org.postgresql.util.PSQLException: ERROR: insert or
>> update on table "test_hijo" violates foreign key constraint "fk_test"
>> Detail: Key (codigo_upc_hijo,id_empresa)=(,se001) is not present in table
>> "test_padre". Error Code: 0 Call: INSERT INTO test_hijo (unidad_medida,
>> id_empresa, codigo_sku) VALUES (?, ?, ?) bind => [unidad Medida, se001,
>> 200]
>> Query:
>> InsertObjectQuery(test.TestHijo[testHijoPK=test.TestHijoPK[codigoSku=200,
>> idEmpresa=se001]]) at 
>>
>> This is Java Code
>>
>>     public TestPadre insertTest(TestPadre padre) {
>>
>>         List<TestHijo> hijos = padre.getTestHijoCollection();
>>         padre.setTestHijoCollection(null);
>>         em.persist(padre);
>>         padre.setTestHijoCollection(hijos);
>>         for (TestHijo hijo : padre.getTestHijoCollection()) {
>>             hijo.setTestPadre(padre);
>>         }
>>         em.merge(padre);
>>         return padre;
>>     }
>>
>> It looks like EclipseLink is not generating the Foreign Key fields on
>> TestHijo.
>>
>> ______________________________________________________________________________________
>>
>>
>>
>>
>>
>>
>> James Sutherland wrote:
>>   
>>> It looks like the TestHijo is being inserted correctly, but the
>>> TestPadre
>>> is not getting inserted first.  Enable logging and see if the insert is
>>> logged for the TestPadre.
>>>
>>>
>>> AntonioJSG wrote:
>>>     
>>>> Hi,
>>>>
>>>> I have a bidirectional oneToMany relationship.
>>>> TestPadre has many TestHijo.
>>>> One joinColumn codigo_upc_hijo is not part of the primary key at the
>>>> owning side of relationship.
>>>> That joinColumn gets null value when trying to persist.
>>>>
>>>> THIS IS THE DATABASE DEFINITION
>>>>
>>>> CREATE TABLE test_padre
>>>> (
>>>>   id_empresa character varying(25) NOT NULL DEFAULT ''::character
>>>> varying,
>>>>   codigo_upc character varying(50) NOT NULL DEFAULT ''::character
>>>> varying,
>>>>   nombre character varying(300) NOT NULL DEFAULT ''::character varying,
>>>>   CONSTRAINT key7 PRIMARY KEY (codigo_upc, id_empresa)
>>>> )
>>>>
>>>> CREATE TABLE test_hijo
>>>> (
>>>>   codigo_sku character varying(50) NOT NULL DEFAULT ''::character
>>>> varying,
>>>>   id_empresa character varying(25) NOT NULL DEFAULT ''::character
>>>> varying,
>>>>   codigo_upc_hijo character varying(50) NOT NULL DEFAULT ''::character
>>>> varying,
>>>>   unidad_medida character varying(25) NOT NULL DEFAULT ''::character
>>>> varying,
>>>>   CONSTRAINT key8 PRIMARY KEY (id_empresa, codigo_sku),
>>>>   CONSTRAINT fk_test FOREIGN KEY (codigo_upc_hijo, id_empresa)
>>>>       REFERENCES test_padre (codigo_upc, id_empresa) MATCH SIMPLE
>>>>       ON UPDATE RESTRICT ON DELETE RESTRICT
>>>> )
>>>>
>>>>
>>>> THESE ARE THE ENTITY MAPPINGS
>>>>
>>>> public class TestPadre implements Serializable {
>>>>     private static final long serialVersionUID = 1L;
>>>>     @EmbeddedId
>>>>     protected TestPadrePK testPadrePK;
>>>>     @Basic(optional = false)
>>>>     @Column(name = "nombre")
>>>>     private String nombre;
>>>>     @OneToMany(cascade = CascadeType.ALL, mappedBy = "testPadre",
>>>> fetch=
>>>> FetchType.EAGER)
>>>>     private List<TestHijo> testHijoCollection;
>>>> (get,set....)
>>>>
>>>>
>>>> @Embeddable
>>>> public class TestPadrePK implements Serializable {
>>>>     @Basic(optional = false)
>>>>     @Column(name = "id_empresa")
>>>>     private String idEmpresa;
>>>>     @Basic(optional = false)
>>>>     @Column(name = "codigo_upc")
>>>>     private String codigoUpc;
>>>>
>>>>
>>>> public class TestHijo implements Serializable {
>>>>     private static final long serialVersionUID = 1L;
>>>>     @EmbeddedId
>>>>     protected TestHijoPK testHijoPK;
>>>>     @Basic(optional = false)
>>>>     @Column(name = "unidad_medida")
>>>>     private String unidadMedida;
>>>>     @JoinColumns({@JoinColumn(name = "codigo_upc_hijo",
>>>> referencedColumnName = "codigo_upc", nullable=false), @JoinColumn(name
>>>> =
>>>> "id_empresa", referencedColumnName = "id_empresa", insertable = false,
>>>> updatable = false)})
>>>>     @ManyToOne(optional = false)
>>>>     private TestPadre testPadre;
>>>> (get,set...)
>>>>
>>>>
>>>> @Embeddable
>>>> public class TestHijoPK implements Serializable {
>>>>     @Basic(optional = false)
>>>>     @Column(name = "codigo_sku")
>>>>     private String codigoSku;
>>>>     @Basic(optional = false)
>>>>     @Column(name = "id_empresa")
>>>>     private String idEmpresa;
>>>>
>>>>
>>>> The data to be persisted is
>>>>
>>>>         TestPadre padre = new TestPadre();
>>>>         TestPadrePK padrePk = new TestPadrePK("se001", "200");
>>>>         padre.setTestPadrePK(padrePk);
>>>>         padre.setNombre("nombre de Test");
>>>>         padre.setTestHijoCollection(new ArrayList<TestHijo>());
>>>>         TestHijo hijo = new TestHijo();
>>>>         TestHijoPK hijoPK = new TestHijoPK("200", "se001", "200");
>>>>         hijo.setTestHijoPK(hijoPK);
>>>>         hijo.setUnidadMedida("unidad Medida");
>>>>         hijo.setTestPadre(padre);
>>>>         padre.getTestHijoCollection().add(hijo);
>>>>
>>>>
>>>> The code to persist is 
>>>>
>>>> public TestPadre insertTest(TestPadre padre) {
>>>>         for (TestHijo hijo : padre.getTestHijoCollection()) {
>>>>             hijo.setTestPadre(padre);
>>>>         }
>>>>         em.persist(padre);
>>>>         return padre;
>>>> }
>>>>
>>>>
>>>> When I try to persist TestPadre I get the following error
>>>>
>>>> Exception [EclipseLink-4002] (Eclipse Persistence Services -
>>>> 1.2.0.v20091016-r5565):
>>>> org.eclipse.persistence.exceptions.DatabaseException Internal
>>>> Exception:
>>>> org.postgresql.util.PSQLException: ERROR: insert or update on table
>>>> "test_hijo" violates foreign key constraint "fk_test" Detail: Key
>>>> (codigo_upc_hijo,id_empresa)=(,se001) is not present in table
>>>> "test_padre". Error Code: 0 Call: INSERT INTO test_hijo (unidad_medida,
>>>> id_empresa, codigo_sku) VALUES (?, ?, ?) bind => [unidad Medida, se001,
>>>> 200] Query:
>>>> InsertObjectQuery(test.TestHijo[testHijoPK=test.TestHijoPK[codigoSku=200,
>>>> idEmpresa=se001]]) at
>>>> org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
>>>> at 
>>>> .....
>>>>
>>>> What Am I doing wrong ?
>>>>
>>>> thank you
>>>>
>>>>
>>>>
>>>>       
>>>     
>>
>>   
> _______________________________________________
> eclipselink-users mailing list
> eclipselink-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
> 
> 

-- 
View this message in context: http://old.nabble.com/OneToMany-does-not-populate-Foreign-Key-or-null-foreign-key-tp27714271p27756256.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.



Back to the top