openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From piltrafeta <piltraf...@gmail.com>
Subject Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
Date Tue, 18 Nov 2008 19:56:50 GMT

Hi!
I'm having a similar problem for a while, maybe you can help me...
My classes are like this :

@Entity
@Table(name = "ASSIGNED_ACTIVITIES")
@IdClass(AssignedActivityPk.class)
public class AssignedActivity implements IsSerializable {
	@Id 
	@Column (name = "CONS_ID", nullable=false)
	private Integer consId;
	@Id 
	@Column (name = "PACT_ID", nullable=false)
	private Integer pactId;
	@Column (name = "TYPE")
	private Integer type;
	@Column (name = "ASG_EST_TIME")
	private Integer asgEstTime;
	@ManyToOne
	@JoinColumn (name = "PACT_ID", nullable=false,
			insertable = false, updatable = false)
	private Activity activity;
...}

@Embeddable
public class AssignedActivityPk implements Serializable {
	@Id 
	@Column (name = "CONS_ID", nullable=false)
	private Integer consId;
	@Id 
	@Column (name = "PACT_ID", nullable=false)
	private Integer pactId;
...}

@Entity
@Table (name="PROJECT_ACTIVITIES")
@SequenceGenerator(name = "SEQ_PACT_ID", sequenceName = "SEQ_PACT_ID",
allocationSize = 1)
public class Activity implements IsSerializable{
	@Id
	@Column(name="PACT_ID", nullable=false)
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"SEQ_PACT_ID")
	private Integer id = null;
	@Column(name="PACT_DESC")
	private String desc = null;
	
	@OneToMany (mappedBy="pactId", fetch = FetchType.LAZY)
	@JoinColumn (name = "PACT_ID", nullable = false)
	@Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
	private Set<AssignedActivity> assignedTo = new HashSet<AssignedActivity>();
	
...}

As the id from the parent class (Activity) is generated by a sequence from
the database, when I'm trying to insert a new Activity, the record for
parent object is correct (the id is generated) but not for the child
(AssignedActivity). So i've the child inserted but width the pact_id = null. 

Have you got any idea of which is the problem??
Thanks !



Fay Wang wrote:
> 
> 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 <egoosen2@metropolitan.co.za> wrote:
> 
>> From: Enrico Goosen <egoosen2@metropolitan.co.za>
>> Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
>> To: users@openjpa.apache.org
>> 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.
> 
> 
>       
> 
> 

-- 
View this message in context: http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1515826.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Mime
View raw message