Hmmm. Here is my test case and it works fine. Four classes are listed:
(1) TblPdtbnf0.java
(2) TblPdtbnfId.java
(3) TblScmpdt0.java
(4) Test0.java
You might still want to try it? :=))
-f
====================================================
(1) TblPdtbnf0.java
package insert;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
@IdClass(TblPdtbnfId.class)
public class TblPdtbnf0 {
@Id
@Column(name = "PDTBNF_ID", nullable = false)
private Integer pdtbnfId;
@Id
@Column(name = "SCMPDT_ID", nullable = false)
private Integer scmpdtId;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
@JoinColumn(name = "XYZ_ID", referencedColumnName = "SCMPDT_ID")
private TblScmpdt0 tblScmpdt;
public Integer getPdtbnfId() {
return pdtbnfId;
}
public void setPdtbnfId(Integer pdtbnfId) {
this.pdtbnfId = pdtbnfId;
}
public Integer getScmpdtId() {
return scmpdtId;
}
public TblScmpdt0 getTblScmpdt() {
return tblScmpdt;
}
public void setTblScmpdt(TblScmpdt0 tblScmpdt) {
this.tblScmpdt = tblScmpdt;
this.scmpdtId = tblScmpdt.getScmpdtId();
}
}
=============================================================
(2)TblPdtbnfId.java
package insert;
import java.io.Serializable;
public class TblPdtbnfId implements Serializable{
private Integer pdtbnfId;
private Integer scmpdtId;
public TblPdtbnfId(){}
public TblPdtbnfId(Integer pdtbnfId, Integer scmpdtId) {
this.pdtbnfId = pdtbnfId;
this.scmpdtId = scmpdtId;
}
public Integer getScmpdtId() {
return scmpdtId;
}
public Integer getPdtbnfId() {
return pdtbnfId;
}
public boolean equals(Object o) {
return (o instanceof TblPdtbnfId) &&
pdtbnfId.intValue() == ((TblPdtbnfId)o).getPdtbnfId().intValue() &&
scmpdtId.intValue() == ((TblPdtbnfId)o).getScmpdtId().intValue();
}
public int hashCode() {
int hc = 0;
if (pdtbnfId != null) hc = hc + pdtbnfId.hashCode();
if (scmpdtId != null) hc = hc + scmpdtId.hashCode();
return hc;
}
}
==============================================
(3)TblScmpdt0.java
package insert;
import java.util.ArrayList;
import java.util.Collection;
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.JoinColumns;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.TableGenerator;
@Entity
public class TblScmpdt0 {
@TableGenerator(name="baseGenerator",schema="EBSTATUS",table="TBL_KEYGEN",
pkColumnName="PRIMARY_KEY_COLUMN",
valueColumnName="LAST_USED_ID",
pkColumnValue="TBL_SCMPDT_ID",allocationSize=100)
@Id
@GeneratedValue(strategy=GenerationType.TABLE,generator="baseGenerator")
@Column(name = "SCMPDT_ID",nullable=false)
private Integer scmpdtId;
@OneToMany(fetch = FetchType.LAZY,
mappedBy="tblScmpdt",
cascade={CascadeType.MERGE,CascadeType.REMOVE,
CascadeType.PERSIST})
private Collection<TblPdtbnf0> tblPdtbnfs = new ArrayList<TblPdtbnf0>();
private String admsysCde;
private String fndCde;
private String gccCde;
public Collection getTblPdtbnfs() {
return tblPdtbnfs;
}
public void setTblPdtbnfs(Collection tblPdtbnfs) {
this.tblPdtbnfs = tblPdtbnfs;
}
public void addTblPdtbnf(TblPdtbnf0 tblPdtbnf) {
tblPdtbnfs.add(tblPdtbnf);
}
public Integer getScmpdtId() {
return scmpdtId;
}
public String getAdmsysCde() {
return admsysCde;
}
public void setAdmsysCde(String admsysCde) {
this.admsysCde = admsysCde;
}
public void setFndCde(String fndCde) {
this.fndCde = fndCde;
}
public String getFndCde(){
return fndCde;
}
public void setGccCde(String gccCde){
this.gccCde = gccCde;
}
public String getGccCde() {
return gccCde;
}
}
========================================================
(4) Test0.java:
package insert;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class Test0 {
public static void main(String[] args) {
try{
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("insert");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
TblScmpdt0 tblScmpdt = new TblScmpdt0();
tblScmpdt.setAdmsysCde("EBSTA");
tblScmpdt.setFndCde("1526");
tblScmpdt.setGccCde("A1526");
TblPdtbnf0 tblPdtbnf = new TblPdtbnf0();
tblPdtbnf.setTblScmpdt(tblScmpdt);
tblScmpdt.addTblPdtbnf(tblPdtbnf);
tblScmpdt = em.merge(tblScmpdt);
em.getTransaction().commit();
} catch (Exception e){
e.printStackTrace();
}
}
}
--- On Tue, 6/17/08, Enrico Goosen <[EMAIL PROTECTED]> wrote:
> From: Enrico Goosen <[EMAIL PROTECTED]>
> Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
> To: [email protected]
> Date: Tuesday, June 17, 2008, 1:32 AM
> Hi Fay,
>
> I tried out your suggestion:
> @ManyToOne(fetch =
> FetchType.LAZY,cascade=CascadeType.MERGE)
> @JoinColumn(name =
> "XYZ_ID",referencedColumnName="SCMPDT_ID")
>
> private TblScmpdt tblScmpdt;
>
> But unfortunately, still no luck.
> Got this exception:
> <openjpa-1.1.0-r422266:657916 fatal store error>
> org.apache.openjpa.persistence.RollbackException: DB2 SQL
> error: SQLCODE:
> -407, SQLSTATE: 23502, SQLERRMC: TBSPACEID=2, TABLEID=263,
> COLNO=0
> at
> org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:523)
> at test.za.co.metcapri.Tester.test(Tester.java:100)
> at test.za.co.metcapri.Tester.main(Tester.java:21)
> Caused by: <openjpa-1.1.0-r422266:657916 nonfatal
> general error>
> org.apache.openjpa.persistence.PersistenceException: DB2
> SQL error: SQLCODE:
> -407, SQLSTATE: 23502, SQLERRMC: TBSPACEID=2, TABLEID=263,
> COLNO=0
> FailedObject: prepstmnt 14779369 INSERT INTO
> EBSTATUS.TBL_PDTBNF (PDTBNF_ID,
> SCMPDT_ID, CMN_DTE) VALUES (?, ?, ?)
> [org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement]
>
> SQLSTATE 23502: An insert or update value is null, but the
> column cannot
> contain null values.
>
> The closest I came to solving this problem was a suggestion
> I saw in the
> Hibernate forums, where a user was experiencing the same
> problem.
> http://forum.hibernate.org/viewtopic.php?t=987126&highlight=detached&sid=48c7ceada0b8df5718275a74d6dcafc4
> http://forum.hibernate.org/viewtopic.php?t=987126&highlight=detached&sid=48c7ceada0b8df5718275a74d6dcafc4
>
>
> I changed TblPdtbnf.class to use an @EmbeddedId:
>
> @EmbeddedId
> private TblPdtbnfPK tblPdtbnfPK;
>
> Changed TblPdtbnfPK to @Embeddable.
>
> I also had to modify the setters on TblPdtbnf like so:
>
> public void setTblScmpdt(TblScmpdt tblScmpdt) {
> this.tblScmpdt = tblScmpdt;
> if(this.tblPdtbnfPK == null){
> this.tblPdtbnfPK = new TblPdtbnfPK();
> }
> if(tblScmpdt != null){
> this.tblPdtbnfPK.setScmpdtId(tblScmpdt.getScmpdtId());
> }
> }
> public void setTblPdtbnfcde(TblPdtbnfcde tblPdtbnfcde) {
> this.tblPdtbnfcde = tblPdtbnfcde;
> if(this.tblPdtbnfPK == null){
> this.tblPdtbnfPK = new TblPdtbnfPK();
> }
> if(tblPdtbnfcde != null){
> this.tblPdtbnfPK.setPdtbnfId(tblPdtbnfcde.getPdtbnfId());
> }
> }
>
> I was able to perform a cascading persist, but when I
> checked the database,
> there were two new columns on TBL_PDTBNF, viz. scmpdtId,
> and pdtbnfId, in
> addition to the existing columns SCMPDT_ID and PDTBNF_ID.
> I tried renaming the fields on TblPdtbnfPK.class to match
> the database
> columns, to prevent this problem, but that didn't help.
>
> As a last resort, I tried switching JPA providers to
> Hibernate, and I found
> that the problem exists in Hibernate as well.
>
> I give up...:-((
> --
> View this message in context:
> http://www.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp17801245p17880499.html
> Sent from the OpenJPA Users mailing list archive at
> Nabble.com.