You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Enrico Goosen <eg...@metropolitan.co.za> on 2008/06/12 16:24:25 UTC

@OneToMany/@ManyToOne, Bidirectional, Composite Key

I can't get cascading persist working on my entities which have the following
mappings.

TblScmpdt.java //Parent
@OneToMany(fetch =
FetchType.LAZY,mappedBy="tblScmpdt",cascade={CascadeType.MERGE,CascadeType.REMOVE})
private Collection<TblPdtbnf> tblPdtbnfs = new ArrayList<TblPdtbnf>();

TblPdtbnf.java //Child
@Id
    @Column(name = "PDTBNF_ID",nullable=false)
    private Integer pdtbnfId;    //Foreign key to TblPdtbnfcde.java

    @Id
    @Column(name = "SCMPDT_ID",nullable=false)
    private Integer scmpdtId; //Foreign key to TblScmpdt.java

 @ManyToOne(fetch = FetchType.LAZY,cascade=CascadeType.MERGE)
    @JoinColumn(name = "SCMPDT_ID",referencedColumnName="SCMPDT_ID") 
    private TblScmpdt tblScmpdt;

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

Here's the test code:

em.getTransaction().begin();
			
			TblScmpdt tblScmpdt = new TblScmpdt();
			tblScmpdt.setAdmsysCde("EBSTA");
			tblScmpdt.setFndCde("1526");
			tblScmpdt.setGccCde("A1526");
			tblScmpdt.setPflcmnDte(new Date());
			
			TblPdtcde tblPdtcde = em.getReference(TblPdtcde.class, new Integer(121));
			TblPdtbnfcde tblPdtbnfcde = em.getReference(TblPdtbnfcde.class, new
Integer(13));
			
			tblScmpdt.setPdtcdeId(tblPdtcde.getPdtcdeId());
			
			TblPdtbnf tblPdtbnf = new TblPdtbnf();
			tblPdtbnf.setCmnDte(new Date());
			tblPdtbnf.setPdtbnfId(tblPdtbnfcde.getPdtbnfId());
			tblPdtbnf.setTblScmpdt(tblScmpdt);
			
			tblScmpdt.addTblPdtbnf(tblPdtbnf);
//			tblScmpdt.getTblPdtbnfs().add(tblPdtbnf);

			tblScmpdt = em.merge(tblScmpdt);
			
			em.getTransaction().commit();

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

The exception:

Caused by: <openjpa-1.0.0-r420667:568756 fatal user error>
org.apache.openjpa.persistence.InvalidStateException: Attempt to set column
"TBL_PDTBNF.SCMPDT_ID" to two different values: (null)"null", (class
java.lang.Integer)"700" This can occur when you fail to set both sides of a
two-sided relation between objects, or when you map different fields to the
same column, but you do not keep the values of these fields in synch.
	at org.apache.openjpa.jdbc.sql.PrimaryRow.setObject(PrimaryRow.java:338)
	at org.apache.openjpa.jdbc.sql.RowImpl.flushJoinValues(RowImpl.java:289)
	at org.apache.openjpa.jdbc.sql.RowImpl.flushForeignKey(RowImpl.java:222)
	at org.apache.openjpa.jdbc.sql.RowImpl.setForeignKey(RowImpl.java:197)
	at
org.apache.openjpa.jdbc.sql.PrimaryRow.setForeignKey(PrimaryRow.java:172)
	at
org.apache.openjpa.jdbc.meta.ValueMappingImpl.setForeignKey(ValueMappingImpl.java:317)
	at
org.apache.openjpa.jdbc.meta.FieldMapping.setForeignKey(FieldMapping.java:966)
	at
org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy.insert(RelationFieldStrategy.java:207)
	at org.apache.openjpa.jdbc.meta.FieldMapping.insert(FieldMapping.java:555)
	at
org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.insert(AbstractUpdateManager.java:203)
	at
org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.populateRowManager(AbstractUpdateManager.java:145)
	at
org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:85)
	at
org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:72)
	at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:514)
	at
org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
	at
org.apache.openjpa.datacache.DataCacheStoreManager.flush(DataCacheStoreManager.java:544)
	at
org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
	... 9 more

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


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key BUG

Posted by Enrico Goosen <eg...@metropolitan.co.za>.
I updated to OpenJPA 1.1.0, and I'm not getting the above exception anymore,
but its still not working 100%.

Updated example code:

em.getTransaction().begin();
			
			TblScmpdt tblScmpdt = new TblScmpdt();
			tblScmpdt.setAdmsysCde("EBSTA");
			tblScmpdt.setFndCde("0001526");
			tblScmpdt.setGccCde("A1526");
			tblScmpdt.setPflcmnDte(new Date());

			TblPdtbnfcde tblPdtbnfcde = em.getReference(TblPdtbnfcde.class, new
Integer(13));
			
			tblScmpdt.setPdtcdeId(tblPdtbnfcde.getTblPdtcde().getPdtcdeId());
			tblScmpdt.setTblPdtcde(tblPdtbnfcde.getTblPdtcde());
			
			//First need to save parent, this wouldn't be necessary if the child
didn't have a composite key
			tblScmpdt = em.merge(tblScmpdt);
			em.flush(); //Have to flush otherwise JPA tries to persist child before
parent
			
			TblPdtbnf tblPdtbnf = new TblPdtbnf();
			tblPdtbnf.setCmnDte(new Date());
			tblPdtbnf.setTblPdtbnfcde(tblPdtbnfcde);
			tblPdtbnf.setPdtbnfId(tblPdtbnfcde.getPdtbnfId());
			tblPdtbnf.setTblScmpdt(tblScmpdt);
			tblPdtbnf.setScmpdtId(tblScmpdt.getScmpdtId()); //this should get done
automatically by JPA
			
			tblScmpdt.getTblPdtbnfs().add(tblPdtbnf);

			//merge again to save child(ren)
			tblScmpdt = em.merge(tblScmpdt);
			
			em.getTransaction().commit();

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


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key BUG

Posted by Enrico Goosen <eg...@metropolitan.co.za>.
This is clearly a bug in OpenJPA, because the IdClass' field is not getting
sychronized with the Entities Id field.
In this case, TblPdtbnf.scmpdtId is not getting copied to
TblPdtbnfPK.scmpdtId.
Hence this error:
Attempt to set column "TBL_PDTBNF.SCMPDT_ID" to two different values:
(null)"null", (class java.lang.Integer)"700"
-- 
View this message in context: http://www.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp17801245p17819665.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Enrico Goosen <eg...@metropolitan.co.za>.
I commented out the @Id fields in:

TblPdtbnf.java

and added:

@EmbeddedId
private TblPdtbnfPK tblPdtbnfPK;

Now I get this exception, which seems more promising, but still no cigar.

Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: DB2 SQL error:
SQLCODE: -530, SQLSTATE: 23503, SQLERRMC: EBSTATUS.TBL_PDTBNF.RCR_PDTBNF_01
{prepstmnt 895244 INSERT INTO EBSTATUS.TBL_PDTBNF (pdtbnfId, scmpdtId,
CMN_DTE, TMN_DTE, VRS_NBR, SCMPDT_ID, PDTBNF_ID) VALUES (?, ?, ?, ?, ?, ?,
?) [params=(null) null, (null) null, (Date) 2008-06-12, (Date) 1001-01-01,
(int) 1, (int) 1500, (int) 13]} [code=-530, state=23503]
	at
org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:192)
	at
org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$800(LoggingConnectionDecorator.java:57)
	at
org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeUpdate(LoggingConnectionDecorator.java:858)
	at
org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:269)
	at
org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement.executeUpdate(JDBCStoreManager.java:1363)
	at
org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:97)
	... 18 more
-- 
View this message in context: http://www.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-tp17801245p17803487.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key BUG

Posted by hfridland <hf...@shaw.ca>.
Hi,
   I have same problem. I have 2 tables on Sybase Anywhere:

@Entity
public class Employee {
   @Id @GeneratedValue
   private Long Id;

   private String name;
...................
}

@Entity
@IdClass(EmpHourId.class)
public class EmpHour {
   @Id
   private Long empId;
   
   @Id
   private Long cpo;
}

My relation is Employee.Id == EmpHour.EmpId. How I can implement it on JPA?
I use Hibernate.
Thanks,
Haim Fridland.
-- 
View this message in context: http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p532204.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Jeremy Bauer <te...@gmail.com>.
Hi Enrico.

Do you have an embedded id or id class defined for TblPdtbnf?  Section
2.1.4 of the JPA spec says the following regarding composite primary
keys:

<spec>A composite primary key must correspond to either a single
persistent field or property or to a set of
such fields or properties as described below. A primary key class must
be defined to represent a composite
primary key. Composite primary keys typically arise when mapping from
legacy databases when the
database key is comprised of several columns. The EmbeddedId and
IdClass annotations are used
to denote composite primary keys. See sections 9.1.14 and 9.1.15. </spec>

If you do not have an embedded id or id class defined, defining one
may correct your problem.  The spec has some good examples of their
usage.

-Jeremy

On Sat, Jun 14, 2008 at 7:46 AM, Enrico Goosen
<eg...@metropolitan.co.za> wrote:
>
> Hi Fay,
>
> The primary key for TblScmpdt is database generated. Here's the mapping:
>
> @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;
>
> As I mentioned in my previous post, the code works (no exceptions), but its
> flawed because of the bug in JPA when performing a cascade persist on a
> OneToMany entity where the child (many) entity has a composite key.
>
> I should simply be able to do the following:
>
> TblScmpdt tblScmpdt = new TblScmpdt(); //new (non-persistent) parent entity
> //set fields on tblScmpdt ...
> TblPdtbnf tblPdtbnf = new TblPdtbnf(); //new (non-persistent) child entity
> //set fields on tblPdtbnf ...
> tblScmpdt.addTblpdtbnf(tblPdtbnf); //see method below, which sets the parent
> referrence on child
>
> //TblScmpdt method:
> public void addTblPdtbnf(TblPdtbnf tblPdtbnf) {
>        tblPdtbnf.setTblScmpdt(this); //need to set both sides of bidirectional
> relationship
>        getTblPdtbnfs().add(tblPdtbnf);
> }
> //Now I should be able to persist parent and cascade persist child
> automatically according to JPA docs
> tblScmpdt = em.merge(tblScmpdt);
>
> ...but unfortunately, the above doesn't work.
> I have to merge/persist the parent first > then get the ID of the newly
> persisted parent and set it on the new child > then add the child to the
> parent > then merge the parent again. Tedious!
>
> Do you understand the problem?
>
> Regarding TblPdtbnfcde, this is a OneToOne reference on TblPdtbnf.
> TblPdtbnf's composite primary key is made up of TblPdtbnfcde.pdtbnfId and
> TblScmpdt.scmpdtId
>
> By the way, cascade persist works fine on my other OneToMany classes where
> there isn't a composite key.
> So this is definitely a bug.
>
>
>
> Enrico,
>
>    What is the primary key field in the TblScmpdt entity? Did you set
> primary key for tblScmpdt before calling merge? I made an integer primary
> key field in TblScmpdt, and set the primary key to 1 in tblScmpdt before
> calling merge, and your test code works fine for me (I also omit
> TblPdtbnfcde in your test code for lack of detailed information). If you
> already set the primary key and still get the error, please specify more
> detail of your TblScmpdt class.
>
>
> -f
>
> --
> View this message in context: http://www.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp17801245p17839130.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>
>

Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Fay Wang <fy...@yahoo.com>.
ok. I can reproduce your problem. Let me take a look.

-f


--- On Sat, 6/14/08, Enrico Goosen <eg...@metropolitan.co.za> wrote:

> From: Enrico Goosen <eg...@metropolitan.co.za>
> Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
> To: users@openjpa.apache.org
> Date: Saturday, June 14, 2008, 5:46 AM
> Hi Fay,
> 
> The primary key for TblScmpdt is database generated.
> Here's the mapping:
> 
> @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; 
> 
> As I mentioned in my previous post, the code works (no
> exceptions), but its
> flawed because of the bug in JPA when performing a cascade
> persist on a
> OneToMany entity where the child (many) entity has a
> composite key.
> 
> I should simply be able to do the following:
> 
> TblScmpdt tblScmpdt = new TblScmpdt(); //new
> (non-persistent) parent entity
> //set fields on tblScmpdt ...
> TblPdtbnf tblPdtbnf = new TblPdtbnf(); //new
> (non-persistent) child entity
> //set fields on tblPdtbnf ...
> tblScmpdt.addTblpdtbnf(tblPdtbnf); //see method below,
> which sets the parent
> referrence on child
> 
> //TblScmpdt method:
> public void addTblPdtbnf(TblPdtbnf tblPdtbnf) {
> 	tblPdtbnf.setTblScmpdt(this); //need to set both sides of
> bidirectional
> relationship
> 	getTblPdtbnfs().add(tblPdtbnf);
> }
> //Now I should be able to persist parent and cascade
> persist child
> automatically according to JPA docs
> tblScmpdt = em.merge(tblScmpdt); 
> 
> ...but unfortunately, the above doesn't work.
> I have to merge/persist the parent first > then get the
> ID of the newly
> persisted parent and set it on the new child > then add
> the child to the
> parent > then merge the parent again. Tedious!
> 
> Do you understand the problem?
> 
> Regarding TblPdtbnfcde, this is a OneToOne reference on
> TblPdtbnf.
> TblPdtbnf's composite primary key is made up of
> TblPdtbnfcde.pdtbnfId and
> TblScmpdt.scmpdtId
> 
> By the way, cascade persist works fine on my other
> OneToMany classes where
> there isn't a composite key.
> So this is definitely a bug.
> 
> 
> 
> Enrico,
> 
>     What is the primary key field in the TblScmpdt entity?
> Did you set
> primary key for tblScmpdt before calling merge? I made an
> integer primary
> key field in TblScmpdt, and set the primary key to 1 in
> tblScmpdt before
> calling merge, and your test code works fine for me (I also
> omit
> TblPdtbnfcde in your test code for lack of detailed
> information). If you
> already set the primary key and still get the error, please
> specify more
> detail of your TblScmpdt class.     
>  
> 
> -f
> 
> -- 
> View this message in context:
> http://www.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp17801245p17839130.html
> Sent from the OpenJPA Users mailing list archive at
> Nabble.com.


      

Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Enrico Goosen <eg...@metropolitan.co.za>.
Hi Fay,

The primary key for TblScmpdt is database generated. Here's the mapping:

@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; 

As I mentioned in my previous post, the code works (no exceptions), but its
flawed because of the bug in JPA when performing a cascade persist on a
OneToMany entity where the child (many) entity has a composite key.

I should simply be able to do the following:

TblScmpdt tblScmpdt = new TblScmpdt(); //new (non-persistent) parent entity
//set fields on tblScmpdt ...
TblPdtbnf tblPdtbnf = new TblPdtbnf(); //new (non-persistent) child entity
//set fields on tblPdtbnf ...
tblScmpdt.addTblpdtbnf(tblPdtbnf); //see method below, which sets the parent
referrence on child

//TblScmpdt method:
public void addTblPdtbnf(TblPdtbnf tblPdtbnf) {
	tblPdtbnf.setTblScmpdt(this); //need to set both sides of bidirectional
relationship
	getTblPdtbnfs().add(tblPdtbnf);
}
//Now I should be able to persist parent and cascade persist child
automatically according to JPA docs
tblScmpdt = em.merge(tblScmpdt); 

...but unfortunately, the above doesn't work.
I have to merge/persist the parent first > then get the ID of the newly
persisted parent and set it on the new child > then add the child to the
parent > then merge the parent again. Tedious!

Do you understand the problem?

Regarding TblPdtbnfcde, this is a OneToOne reference on TblPdtbnf.
TblPdtbnf's composite primary key is made up of TblPdtbnfcde.pdtbnfId and
TblScmpdt.scmpdtId

By the way, cascade persist works fine on my other OneToMany classes where
there isn't a composite key.
So this is definitely a bug.



Enrico,

    What is the primary key field in the TblScmpdt entity? Did you set
primary key for tblScmpdt before calling merge? I made an integer primary
key field in TblScmpdt, and set the primary key to 1 in tblScmpdt before
calling merge, and your test code works fine for me (I also omit
TblPdtbnfcde in your test code for lack of detailed information). If you
already set the primary key and still get the error, please specify more
detail of your TblScmpdt class.     
 

-f

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


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by piltrafeta <pi...@gmail.com>.
Hi Fay!
I'm still blocked.. do you have any idea?

Thanks!

On Thu, Nov 20, 2008 at 6:24 PM, piltrafeta <pi...@gmail.com> wrote:

> Hi Fay!
>
> Thank you for your explanation, it's exactly what i want to do. But i don't
> know exactly how to set pactId as Foreign Key..
> Now i'm having the exception that pact_id could not be NULL, so pactId it's
> not being setted..
> My code is:
>
> @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="activity", fetch = FetchType.LAZY)
>     @JoinColumn (name = "PACT_ID", nullable = false)//, insertable = false,
> updatable = false)
>     @Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
>     private Set<AssignedActivity> assignedTo = new
> HashSet<AssignedActivity>();
>     ..}
>
> @Entity
> @Table(name = "ASSIGNED_ACTIVITIES")
> public class AssignedActivity implements IsSerializable {
>     @Id
>     @Column (name = "CONS_ID", nullable=false)
>     private Integer consId;
>
>     @Column (name = "PACT_ID", nullable=false)
>     private Integer pactId;
>
>     @ManyToOne
>     @JoinColumn (name = "PACT_ID", referencedColumnName = "PACT_ID",
>             nullable=false,    insertable = false, updatable = false)
>     private Activity activity = new Activity();
>     ..}
>
>
> Thank you very much for your help!
> Regards,
> Eli
>
>
> On Wed, Nov 19, 2008 at 7:05 PM, Fay Wang (via Nabble) <
> ml-user+18167-539011811@n2.nabble.com<ml...@n2.nabble.com>
> > wrote:
>
>> Hi, Eli,
>>    It seems that you want to have pactId as a primary key and join column
>> in the assigned_activities (child) table, and you want the pactId
>> automatically generated in the project_activities (parent) table to fill in
>> the pactId column (it is a primary key column) in the child table. I got the
>> following error when trying to persist an Activity entity with two
>> AssignedActivity objects to the database because PACT_ID column is both a
>> primary key column and a foreign key column:
>>
>> <openjpa-0.0.0-rnull fatal user error>
>> org.apache.openjpa.util.InvalidStateException: Attempt to set column
>> "ASSIGNED_ACTIVITIES.PACT_ID" to two different values: (class
>> java.lang.Integer)"0", (class java.lang.Integer)"7" This can occur when you
>> fail to set both sides of a two-sided relation between objects, or when you
>> map different fields to the same column, but you do not keep the values of
>> these fields in synch.
>>
>>
>> The workaround is not to use IdClass. Instead, to have consId alone as the
>> primary key in the child table and pactId as the join column (foreign key
>> column) in the child table. Hope this is helpful.
>>
>> Fay
>>
>>
>> --- On Wed, 11/19/08, piltrafeta <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=0>>
>> wrote:
>>
>> > From: piltrafeta <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=1>>
>>
>> > Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
>> > To: users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=2>
>> > Date: Wednesday, November 19, 2008, 9:38 AM
>> > Hi Fay,
>> > I've done the modification you told me but it's
>> > still not working... when i
>> > insert new registers the pactId from assignedActivities
>> > remains null.
>> >
>> > I copy the class activity with the modification:
>> >
>> > @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;
>> > @Column (name ="STATE")
>> > private Integer state = null;
>> >
>> > @Column (name ="PROJ_ID")
>> > private Integer idProject = null;
>> >
>> > @Column (name ="PACT_DUE_DATE")
>> > private Date dueDate = null;
>> >
>> > @OneToMany (mappedBy="activity", fetch =
>> > FetchType.LAZY)
>> > @JoinColumn (name = "PACT_ID", nullable = false)
>> > @Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
>> > private Set<AssignedActivity> assignedTo = new
>> > HashSet<AssignedActivity>();
>> > ..}
>> >
>> > Regards,
>> > Eli
>> >
>> >
>> > Fay Wang wrote:
>> > >
>> > > Hi,
>> > >    In your test case, you have OneToMany relation from
>> > Activity to
>> > > AssignedActivity. The mappedBy attribute in the
>> > OneToMany relation should
>> > > be the name of the many-to-one field in the related
>> > entity that maps this
>> > > bidirectional relation. Could you change mappedBy to
>> > "activity" and try
>> > > again?
>> > >
>> > > Regards,
>> > > Fay
>> > >
>> > >
>> > >
>> > >
>> > >
>> > > --- On Tue, 11/18/08, piltrafeta
>> > <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=3>>
>> wrote:
>> > >
>> > >> From: piltrafeta <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=4>>
>>
>> > >> Subject: Re: @OneToMany/@ManyToOne, Bidirectional,
>> > Composite Key
>> > >> To: users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=5>
>> > >> Date: Tuesday, November 18, 2008, 11:56 AM
>> > >> 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@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=6>>
>> wrote:
>> > >> >
>> > >> >> From: Enrico Goosen
>> > >> <egoosen2@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=7>>
>>
>> > >> >> Subject: Re: @OneToMany/@ManyToOne,
>> > Bidirectional,
>> > >> Composite Key
>> > >> >> To: users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=8>
>> > >> >> 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.
>> > >
>> > >
>> > >
>> > >
>> > >
>> >
>> > --
>> > View this message in context:
>> >
>> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1519911.html
>> > Sent from the OpenJPA Users mailing list archive at
>> > Nabble.com.
>>
>>
>>
>>
>>
>> ------------------------------
>>  This email is a reply to your post @
>> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1520608.html
>> You can reply by email or by visting the link above.
>>
>>
>

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

Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Fay Wang <fy...@yahoo.com>.
Hi, Eli,
   In case you did not receive this mail. Please let me know if you have further question. Thanks!

Regards,
Fay



--- On Fri, 11/21/08, Fay Wang <fy...@yahoo.com> wrote:

> From: Fay Wang <fy...@yahoo.com>
> Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
> To: users@openjpa.apache.org
> Date: Friday, November 21, 2008, 8:55 AM
> Hi, Eli,
> 
> The following are my modification of your codes and my test
> case. Note that I get rid of your AssignedActivityPk. The
> insert is working fine. Hope this help!
> 
> Regards,
> Fay
> 
> =====================================
> 
> @Entity
> @Table (name="PROJECT_ACTIVITIES")
> @SequenceGenerator(name = "SEQ_PACT_ID",
> sequenceName = "SEQ_PACT_ID",
> allocationSize = 1)
> public class Activity implements Serializable {
>     @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="activity", fetch =
> FetchType.LAZY, 
>          cascade={CascadeType.ALL})
>     private Set<AssignedActivity> assignedTo = 
>          new HashSet<AssignedActivity>();
> ...
>    }
> 
> ==============================================
> @Entity
> @Table(name = "ASSIGNED_ACTIVITIES")
> public class AssignedActivity implements Serializable{
>     @Id
>     @Column (name = "CONS_ID", nullable=false)
>     private Integer consId;
>     
>     @Column (name = "TYPE")
>     private Integer type;
>     
>     @Column (name = "ASG_EST_TIME")
>     private Integer asgEstTime;
>     
>     @ManyToOne
>     @JoinColumn (name = "PACT_ID",
> nullable=false)
>     @ForeignKey
>     private Activity activity;
>   
> ....
>   }
> ===================================
> The test case:
>     EntityTransaction tran = em.getTransaction();
> 		
>     Activity a = new Activity();
>     a.setDesc("This is a1");
> 		
>     AssignedActivity aa = new AssignedActivity();
>     aa.setConsId(1);
>     aa.setAsgEstTime(1);
>     aa.setType(1);
>     aa.setActivity(a);
>     a.addAssignedTo(aa);
>         
>     AssignedActivity aa2 = new AssignedActivity();
>     aa2.setConsId(2);
>     aa2.setAsgEstTime(2);
>     aa2.setType(2);
>     aa2.setActivity(a);
>     a.addAssignedTo(aa2);
>         
>     tran.begin();
>     em.persist(a);
>     em.persist(aa);
>     em.persist(aa2);
>     tran.commit();
>     em.close();
> 
> 
> 
> 
> 
> 
> --- On Thu, 11/20/08, piltrafeta
> <pi...@gmail.com> wrote:
> 
> > From: piltrafeta <pi...@gmail.com>
> > Subject: Re: @OneToMany/@ManyToOne, Bidirectional,
> Composite Key
> > To: users@openjpa.apache.org
> > Date: Thursday, November 20, 2008, 12:24 PM
> > Hi Fay!
> > 
> > Thank you for your explanation, it's exactly what
> i
> > want to do. But i don't
> > know exactly how to set pactId as Foreign Key..
> > Now i'm having the exception that pact_id could
> not be
> > NULL, so pactId it's
> > not being setted..
> > My code is:
> > 
> > @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="activity", fetch =
> > FetchType.LAZY)
> >     @JoinColumn (name = "PACT_ID", nullable
> =
> > false)//, insertable = false,
> > updatable = false)
> >    
> @Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
> >     private Set<AssignedActivity> assignedTo =
> new
> > HashSet<AssignedActivity>();
> >     ..}
> > 
> > @Entity
> > @Table(name = "ASSIGNED_ACTIVITIES")
> > public class AssignedActivity implements
> IsSerializable {
> >     @Id
> >     @Column (name = "CONS_ID",
> nullable=false)
> >     private Integer consId;
> > 
> >     @Column (name = "PACT_ID",
> nullable=false)
> >     private Integer pactId;
> > 
> >     @ManyToOne
> >     @JoinColumn (name = "PACT_ID",
> > referencedColumnName = "PACT_ID",
> >             nullable=false,    insertable = false,
> > updatable = false)
> >     private Activity activity = new Activity();
> >     ..}
> > 
> > 
> > Thank you very much for your help!
> > Regards,
> > Eli
> > 
> > On Wed, Nov 19, 2008 at 7:05 PM, Fay Wang (via Nabble)
> <
> >
> ml-user+18167-539011811@n2.nabble.com<ml...@n2.nabble.com>
> > > wrote:
> > 
> > > Hi, Eli,
> > >    It seems that you want to have pactId as a
> primary
> > key and join column
> > > in the assigned_activities (child) table, and you
> want
> > the pactId
> > > automatically generated in the project_activities
> > (parent) table to fill in
> > > the pactId column (it is a primary key column) in
> the
> > child table. I got the
> > > following error when trying to persist an
> Activity
> > entity with two
> > > AssignedActivity objects to the database because
> > PACT_ID column is both a
> > > primary key column and a foreign key column:
> > >
> > > <openjpa-0.0.0-rnull fatal user error>
> > > org.apache.openjpa.util.InvalidStateException:
> Attempt
> > to set column
> > > "ASSIGNED_ACTIVITIES.PACT_ID" to two
> > different values: (class
> > > java.lang.Integer)"0", (class
> > java.lang.Integer)"7" This can occur when
> you
> > > fail to set both sides of a two-sided relation
> between
> > objects, or when you
> > > map different fields to the same column, but you
> do
> > not keep the values of
> > > these fields in synch.
> > >
> > >
> > > The workaround is not to use IdClass. Instead, to
> have
> > consId alone as the
> > > primary key in the child table and pactId as the
> join
> > column (foreign key
> > > column) in the child table. Hope this is helpful.
> > >
> > > Fay
> > >
> > >
> > > --- On Wed, 11/19/08, piltrafeta
> >
> <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=0>>
> > > wrote:
> > >
> > > > From: piltrafeta
> >
> <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=1>>
> > >
> > > > Subject: Re: @OneToMany/@ManyToOne,
> > Bidirectional, Composite Key
> > > > To:
> >
> users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=2>
> > > > Date: Wednesday, November 19, 2008, 9:38 AM
> > > > Hi Fay,
> > > > I've done the modification you told me
> but
> > it's
> > > > still not working... when i
> > > > insert new registers the pactId from
> > assignedActivities
> > > > remains null.
> > > >
> > > > I copy the class activity with the
> modification:
> > > >
> > > > @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;
> > > > @Column (name ="STATE")
> > > > private Integer state = null;
> > > >
> > > > @Column (name ="PROJ_ID")
> > > > private Integer idProject = null;
> > > >
> > > > @Column (name ="PACT_DUE_DATE")
> > > > private Date dueDate = null;
> > > >
> > > > @OneToMany (mappedBy="activity",
> fetch
> > =
> > > > FetchType.LAZY)
> > > > @JoinColumn (name = "PACT_ID",
> nullable
> > = false)
> > > >
> > @Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
> > > > private Set<AssignedActivity>
> assignedTo =
> > new
> > > > HashSet<AssignedActivity>();
> > > > ..}
> > > >
> > > > Regards,
> > > > Eli
> > > >
> > > >
> > > > Fay Wang wrote:
> > > > >
> > > > > Hi,
> > > > >    In your test case, you have
> OneToMany
> > relation from
> > > > Activity to
> > > > > AssignedActivity. The mappedBy
> attribute in
> > the
> > > > OneToMany relation should
> > > > > be the name of the many-to-one field in
> the
> > related
> > > > entity that maps this
> > > > > bidirectional relation. Could you
> change
> > mappedBy to
> > > > "activity" and try
> > > > > again?
> > > > >
> > > > > Regards,
> > > > > Fay
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > --- On Tue, 11/18/08, piltrafeta
> > > >
> >
> <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=3>>
> > > wrote:
> > > > >
> > > > >> From: piltrafeta
> >
> <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=4>>
> > >
> > > > >> Subject: Re: @OneToMany/@ManyToOne,
> > Bidirectional,
> > > > Composite Key
> > > > >> To:
> >
> users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=5>
> > > > >> Date: Tuesday, November 18, 2008,
> 11:56
> > AM
> > > > >> 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@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=6>>
> > > wrote:
> > > > >> >
> > > > >> >> From: Enrico Goosen
> > > > >>
> >
> <egoosen2@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=7>>
> > >
> > > > >> >> Subject: Re:
> > @OneToMany/@ManyToOne,
> > > > Bidirectional,
> > > > >> Composite Key
> > > > >> >> To:
> >
> users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=8>
> > > > >> >> 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.
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > >
> > > > --
> > > > View this message in context:
> > > >
> > >
> >
> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1519911.html
> > > > Sent from the OpenJPA Users mailing list
> archive
> > at
> > > > Nabble.com.
> > >
> > >
> > >
> > >
> > >
> > > ------------------------------
> > >  This email is a reply to your post @
> > >
> >
> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1520608.html
> > > You can reply by email or by visting the link
> above.
> > >
> > >
> > 
> > -- 
> > View this message in context:
> >
> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1558742.html
> > Sent from the OpenJPA Users mailing list archive at
> > Nabble.com.


      

Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Fay Wang <fy...@yahoo.com>.
Hi, Eli,

The following are my modification of your codes and my test case. Note that I get rid of your AssignedActivityPk. The insert is working fine. Hope this help!

Regards,
Fay

=====================================

@Entity
@Table (name="PROJECT_ACTIVITIES")
@SequenceGenerator(name = "SEQ_PACT_ID", sequenceName = "SEQ_PACT_ID",
allocationSize = 1)
public class Activity implements Serializable {
    @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="activity", fetch = FetchType.LAZY, 
         cascade={CascadeType.ALL})
    private Set<AssignedActivity> assignedTo = 
         new HashSet<AssignedActivity>();
...
   }

==============================================
@Entity
@Table(name = "ASSIGNED_ACTIVITIES")
public class AssignedActivity implements Serializable{
    @Id
    @Column (name = "CONS_ID", nullable=false)
    private Integer consId;
    
    @Column (name = "TYPE")
    private Integer type;
    
    @Column (name = "ASG_EST_TIME")
    private Integer asgEstTime;
    
    @ManyToOne
    @JoinColumn (name = "PACT_ID", nullable=false)
    @ForeignKey
    private Activity activity;
  
....
  }
===================================
The test case:
    EntityTransaction tran = em.getTransaction();
		
    Activity a = new Activity();
    a.setDesc("This is a1");
		
    AssignedActivity aa = new AssignedActivity();
    aa.setConsId(1);
    aa.setAsgEstTime(1);
    aa.setType(1);
    aa.setActivity(a);
    a.addAssignedTo(aa);
        
    AssignedActivity aa2 = new AssignedActivity();
    aa2.setConsId(2);
    aa2.setAsgEstTime(2);
    aa2.setType(2);
    aa2.setActivity(a);
    a.addAssignedTo(aa2);
        
    tran.begin();
    em.persist(a);
    em.persist(aa);
    em.persist(aa2);
    tran.commit();
    em.close();






--- On Thu, 11/20/08, piltrafeta <pi...@gmail.com> wrote:

> From: piltrafeta <pi...@gmail.com>
> Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
> To: users@openjpa.apache.org
> Date: Thursday, November 20, 2008, 12:24 PM
> Hi Fay!
> 
> Thank you for your explanation, it's exactly what i
> want to do. But i don't
> know exactly how to set pactId as Foreign Key..
> Now i'm having the exception that pact_id could not be
> NULL, so pactId it's
> not being setted..
> My code is:
> 
> @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="activity", fetch =
> FetchType.LAZY)
>     @JoinColumn (name = "PACT_ID", nullable =
> false)//, insertable = false,
> updatable = false)
>     @Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
>     private Set<AssignedActivity> assignedTo = new
> HashSet<AssignedActivity>();
>     ..}
> 
> @Entity
> @Table(name = "ASSIGNED_ACTIVITIES")
> public class AssignedActivity implements IsSerializable {
>     @Id
>     @Column (name = "CONS_ID", nullable=false)
>     private Integer consId;
> 
>     @Column (name = "PACT_ID", nullable=false)
>     private Integer pactId;
> 
>     @ManyToOne
>     @JoinColumn (name = "PACT_ID",
> referencedColumnName = "PACT_ID",
>             nullable=false,    insertable = false,
> updatable = false)
>     private Activity activity = new Activity();
>     ..}
> 
> 
> Thank you very much for your help!
> Regards,
> Eli
> 
> On Wed, Nov 19, 2008 at 7:05 PM, Fay Wang (via Nabble) <
> ml-user+18167-539011811@n2.nabble.com<ml...@n2.nabble.com>
> > wrote:
> 
> > Hi, Eli,
> >    It seems that you want to have pactId as a primary
> key and join column
> > in the assigned_activities (child) table, and you want
> the pactId
> > automatically generated in the project_activities
> (parent) table to fill in
> > the pactId column (it is a primary key column) in the
> child table. I got the
> > following error when trying to persist an Activity
> entity with two
> > AssignedActivity objects to the database because
> PACT_ID column is both a
> > primary key column and a foreign key column:
> >
> > <openjpa-0.0.0-rnull fatal user error>
> > org.apache.openjpa.util.InvalidStateException: Attempt
> to set column
> > "ASSIGNED_ACTIVITIES.PACT_ID" to two
> different values: (class
> > java.lang.Integer)"0", (class
> java.lang.Integer)"7" This can occur when you
> > fail to set both sides of a two-sided relation between
> objects, or when you
> > map different fields to the same column, but you do
> not keep the values of
> > these fields in synch.
> >
> >
> > The workaround is not to use IdClass. Instead, to have
> consId alone as the
> > primary key in the child table and pactId as the join
> column (foreign key
> > column) in the child table. Hope this is helpful.
> >
> > Fay
> >
> >
> > --- On Wed, 11/19/08, piltrafeta
> <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=0>>
> > wrote:
> >
> > > From: piltrafeta
> <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=1>>
> >
> > > Subject: Re: @OneToMany/@ManyToOne,
> Bidirectional, Composite Key
> > > To:
> users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=2>
> > > Date: Wednesday, November 19, 2008, 9:38 AM
> > > Hi Fay,
> > > I've done the modification you told me but
> it's
> > > still not working... when i
> > > insert new registers the pactId from
> assignedActivities
> > > remains null.
> > >
> > > I copy the class activity with the modification:
> > >
> > > @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;
> > > @Column (name ="STATE")
> > > private Integer state = null;
> > >
> > > @Column (name ="PROJ_ID")
> > > private Integer idProject = null;
> > >
> > > @Column (name ="PACT_DUE_DATE")
> > > private Date dueDate = null;
> > >
> > > @OneToMany (mappedBy="activity", fetch
> =
> > > FetchType.LAZY)
> > > @JoinColumn (name = "PACT_ID", nullable
> = false)
> > >
> @Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
> > > private Set<AssignedActivity> assignedTo =
> new
> > > HashSet<AssignedActivity>();
> > > ..}
> > >
> > > Regards,
> > > Eli
> > >
> > >
> > > Fay Wang wrote:
> > > >
> > > > Hi,
> > > >    In your test case, you have OneToMany
> relation from
> > > Activity to
> > > > AssignedActivity. The mappedBy attribute in
> the
> > > OneToMany relation should
> > > > be the name of the many-to-one field in the
> related
> > > entity that maps this
> > > > bidirectional relation. Could you change
> mappedBy to
> > > "activity" and try
> > > > again?
> > > >
> > > > Regards,
> > > > Fay
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > --- On Tue, 11/18/08, piltrafeta
> > >
> <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=3>>
> > wrote:
> > > >
> > > >> From: piltrafeta
> <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=4>>
> >
> > > >> Subject: Re: @OneToMany/@ManyToOne,
> Bidirectional,
> > > Composite Key
> > > >> To:
> users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=5>
> > > >> Date: Tuesday, November 18, 2008, 11:56
> AM
> > > >> 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@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=6>>
> > wrote:
> > > >> >
> > > >> >> From: Enrico Goosen
> > > >>
> <egoosen2@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=7>>
> >
> > > >> >> Subject: Re:
> @OneToMany/@ManyToOne,
> > > Bidirectional,
> > > >> Composite Key
> > > >> >> To:
> users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=8>
> > > >> >> 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.
> > > >
> > > >
> > > >
> > > >
> > > >
> > >
> > > --
> > > View this message in context:
> > >
> >
> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1519911.html
> > > Sent from the OpenJPA Users mailing list archive
> at
> > > Nabble.com.
> >
> >
> >
> >
> >
> > ------------------------------
> >  This email is a reply to your post @
> >
> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1520608.html
> > You can reply by email or by visting the link above.
> >
> >
> 
> -- 
> View this message in context:
> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1558742.html
> Sent from the OpenJPA Users mailing list archive at
> Nabble.com.


      

Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by piltrafeta <pi...@gmail.com>.
Hi Fay!

Thank you for your explanation, it's exactly what i want to do. But i don't
know exactly how to set pactId as Foreign Key..
Now i'm having the exception that pact_id could not be NULL, so pactId it's
not being setted..
My code is:

@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="activity", fetch = FetchType.LAZY)
    @JoinColumn (name = "PACT_ID", nullable = false)//, insertable = false,
updatable = false)
    @Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
    private Set<AssignedActivity> assignedTo = new
HashSet<AssignedActivity>();
    ..}

@Entity
@Table(name = "ASSIGNED_ACTIVITIES")
public class AssignedActivity implements IsSerializable {
    @Id
    @Column (name = "CONS_ID", nullable=false)
    private Integer consId;

    @Column (name = "PACT_ID", nullable=false)
    private Integer pactId;

    @ManyToOne
    @JoinColumn (name = "PACT_ID", referencedColumnName = "PACT_ID",
            nullable=false,    insertable = false, updatable = false)
    private Activity activity = new Activity();
    ..}


Thank you very much for your help!
Regards,
Eli

On Wed, Nov 19, 2008 at 7:05 PM, Fay Wang (via Nabble) <
ml-user+18167-539011811@n2.nabble.com<ml...@n2.nabble.com>
> wrote:

> Hi, Eli,
>    It seems that you want to have pactId as a primary key and join column
> in the assigned_activities (child) table, and you want the pactId
> automatically generated in the project_activities (parent) table to fill in
> the pactId column (it is a primary key column) in the child table. I got the
> following error when trying to persist an Activity entity with two
> AssignedActivity objects to the database because PACT_ID column is both a
> primary key column and a foreign key column:
>
> <openjpa-0.0.0-rnull fatal user error>
> org.apache.openjpa.util.InvalidStateException: Attempt to set column
> "ASSIGNED_ACTIVITIES.PACT_ID" to two different values: (class
> java.lang.Integer)"0", (class java.lang.Integer)"7" This can occur when you
> fail to set both sides of a two-sided relation between objects, or when you
> map different fields to the same column, but you do not keep the values of
> these fields in synch.
>
>
> The workaround is not to use IdClass. Instead, to have consId alone as the
> primary key in the child table and pactId as the join column (foreign key
> column) in the child table. Hope this is helpful.
>
> Fay
>
>
> --- On Wed, 11/19/08, piltrafeta <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=0>>
> wrote:
>
> > From: piltrafeta <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=1>>
>
> > Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
> > To: users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=2>
> > Date: Wednesday, November 19, 2008, 9:38 AM
> > Hi Fay,
> > I've done the modification you told me but it's
> > still not working... when i
> > insert new registers the pactId from assignedActivities
> > remains null.
> >
> > I copy the class activity with the modification:
> >
> > @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;
> > @Column (name ="STATE")
> > private Integer state = null;
> >
> > @Column (name ="PROJ_ID")
> > private Integer idProject = null;
> >
> > @Column (name ="PACT_DUE_DATE")
> > private Date dueDate = null;
> >
> > @OneToMany (mappedBy="activity", fetch =
> > FetchType.LAZY)
> > @JoinColumn (name = "PACT_ID", nullable = false)
> > @Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
> > private Set<AssignedActivity> assignedTo = new
> > HashSet<AssignedActivity>();
> > ..}
> >
> > Regards,
> > Eli
> >
> >
> > Fay Wang wrote:
> > >
> > > Hi,
> > >    In your test case, you have OneToMany relation from
> > Activity to
> > > AssignedActivity. The mappedBy attribute in the
> > OneToMany relation should
> > > be the name of the many-to-one field in the related
> > entity that maps this
> > > bidirectional relation. Could you change mappedBy to
> > "activity" and try
> > > again?
> > >
> > > Regards,
> > > Fay
> > >
> > >
> > >
> > >
> > >
> > > --- On Tue, 11/18/08, piltrafeta
> > <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=3>>
> wrote:
> > >
> > >> From: piltrafeta <piltrafeta@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=4>>
>
> > >> Subject: Re: @OneToMany/@ManyToOne, Bidirectional,
> > Composite Key
> > >> To: users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=5>
> > >> Date: Tuesday, November 18, 2008, 11:56 AM
> > >> 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@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=6>>
> wrote:
> > >> >
> > >> >> From: Enrico Goosen
> > >> <egoosen2@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=7>>
>
> > >> >> Subject: Re: @OneToMany/@ManyToOne,
> > Bidirectional,
> > >> Composite Key
> > >> >> To: users@...<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1520608&i=8>
> > >> >> 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.
> > >
> > >
> > >
> > >
> > >
> >
> > --
> > View this message in context:
> >
> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1519911.html
> > Sent from the OpenJPA Users mailing list archive at
> > Nabble.com.
>
>
>
>
>
> ------------------------------
>  This email is a reply to your post @
> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1520608.html
> You can reply by email or by visting the link above.
>
>

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

Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Fay Wang <fy...@yahoo.com>.
Hi, Eli,
   It seems that you want to have pactId as a primary key and join column in the assigned_activities (child) table, and you want the pactId automatically generated in the project_activities (parent) table to fill in the pactId column (it is a primary key column) in the child table. I got the following error when trying to persist an Activity entity with two AssignedActivity objects to the database because PACT_ID column is both a primary key column and a foreign key column:

<openjpa-0.0.0-rnull fatal user error> org.apache.openjpa.util.InvalidStateException: Attempt to set column "ASSIGNED_ACTIVITIES.PACT_ID" to two different values: (class java.lang.Integer)"0", (class java.lang.Integer)"7" This can occur when you fail to set both sides of a two-sided relation between objects, or when you map different fields to the same column, but you do not keep the values of these fields in synch.


The workaround is not to use IdClass. Instead, to have consId alone as the primary key in the child table and pactId as the join column (foreign key column) in the child table. Hope this is helpful.

Fay


--- On Wed, 11/19/08, piltrafeta <pi...@gmail.com> wrote:

> From: piltrafeta <pi...@gmail.com>
> Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
> To: users@openjpa.apache.org
> Date: Wednesday, November 19, 2008, 9:38 AM
> Hi Fay,
> I've done the modification you told me but it's
> still not working... when i
> insert new registers the pactId from assignedActivities
> remains null.
> 
> I copy the class activity with the modification:
> 
> @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;
> 	@Column (name ="STATE")
> 	private Integer state = null;
> 	
> 	@Column (name ="PROJ_ID")
> 	private Integer idProject = null;
> 	
> 	@Column (name ="PACT_DUE_DATE")
> 	private Date dueDate = null;
> 	
> 	@OneToMany (mappedBy="activity", fetch =
> FetchType.LAZY)
> 	@JoinColumn (name = "PACT_ID", nullable = false)
> 	@Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
> 	private Set<AssignedActivity> assignedTo = new
> HashSet<AssignedActivity>();
> ..}
> 
> Regards,
> Eli
> 
> 
> Fay Wang wrote:
> > 
> > Hi,
> >    In your test case, you have OneToMany relation from
> Activity to
> > AssignedActivity. The mappedBy attribute in the
> OneToMany relation should
> > be the name of the many-to-one field in the related
> entity that maps this
> > bidirectional relation. Could you change mappedBy to
> "activity" and try
> > again?
> > 
> > Regards,
> > Fay
> > 
> > 
> > 
> > 
> > 
> > --- On Tue, 11/18/08, piltrafeta
> <pi...@gmail.com> wrote:
> > 
> >> From: piltrafeta <pi...@gmail.com>
> >> Subject: Re: @OneToMany/@ManyToOne, Bidirectional,
> Composite Key
> >> To: users@openjpa.apache.org
> >> Date: Tuesday, November 18, 2008, 11:56 AM
> >> 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
> >> <eg...@metropolitan.co.za> wrote:
> >> > 
> >> >> From: Enrico Goosen
> >> <eg...@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.
> > 
> > 
> >       
> > 
> > 
> 
> -- 
> View this message in context:
> http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p1519911.html
> Sent from the OpenJPA Users mailing list archive at
> Nabble.com.


      

Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by piltrafeta <pi...@gmail.com>.
Hi Fay,
I've done the modification you told me but it's still not working... when i
insert new registers the pactId from assignedActivities remains null.

I copy the class activity with the modification:

@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;
	@Column (name ="STATE")
	private Integer state = null;
	
	@Column (name ="PROJ_ID")
	private Integer idProject = null;
	
	@Column (name ="PACT_DUE_DATE")
	private Date dueDate = null;
	
	@OneToMany (mappedBy="activity", fetch = FetchType.LAZY)
	@JoinColumn (name = "PACT_ID", nullable = false)
	@Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
	private Set<AssignedActivity> assignedTo = new HashSet<AssignedActivity>();
..}

Regards,
Eli


Fay Wang wrote:
> 
> Hi,
>    In your test case, you have OneToMany relation from Activity to
> AssignedActivity. The mappedBy attribute in the OneToMany relation should
> be the name of the many-to-one field in the related entity that maps this
> bidirectional relation. Could you change mappedBy to "activity" and try
> again?
> 
> Regards,
> Fay
> 
> 
> 
> 
> 
> --- On Tue, 11/18/08, piltrafeta <pi...@gmail.com> wrote:
> 
>> From: piltrafeta <pi...@gmail.com>
>> Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
>> To: users@openjpa.apache.org
>> Date: Tuesday, November 18, 2008, 11:56 AM
>> 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
>> <eg...@metropolitan.co.za> wrote:
>> > 
>> >> From: Enrico Goosen
>> <eg...@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.
> 
> 
>       
> 
> 

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


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Fay Wang <fy...@yahoo.com>.
Hi,
   In your test case, you have OneToMany relation from Activity to AssignedActivity. The mappedBy attribute in the OneToMany relation should be the name of the many-to-one field in the related entity that maps this bidirectional relation. Could you change mappedBy to "activity" and try again?

Regards,
Fay





--- On Tue, 11/18/08, piltrafeta <pi...@gmail.com> wrote:

> From: piltrafeta <pi...@gmail.com>
> Subject: Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key
> To: users@openjpa.apache.org
> Date: Tuesday, November 18, 2008, 11:56 AM
> 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
> <eg...@metropolitan.co.za> wrote:
> > 
> >> From: Enrico Goosen
> <eg...@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.


      

Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by piltrafeta <pi...@gmail.com>.
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 <eg...@metropolitan.co.za> wrote:
> 
>> From: Enrico Goosen <eg...@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.


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by egoosen <eg...@metropolitan.co.za>.
Just want to update this post in case someone else stubbles on the same
problems that we did.
My colleague (who's a OpenJPA Ninja) rewrote our DAO's to overcome the
problems I mentioned before.
This included adding the OpenJPA specific annotation @ForeignKey to
@ManyToOne relationships, cos otherwise DB2 tries to insert a child entity
before a parent entity. Apparently this isn't required for MySQL.
PS. I'm not sure if this annotation has been added to the OpenJPA docs
recently, but it wasn't mentioned anywhere in the 1.0.2 manual.
He also added methods to synchronize parent and child relationships.
This can be done be defining a BaseEntity from which all JPA entities
extend, that implement these methods.
So, after em.merge and before transaction commit, synch the relationships,
and all will be fine.
-- 
View this message in context: http://n2.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-BUG-tp210672p221083.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Fay Wang <fy...@yahoo.com>.
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 <eg...@metropolitan.co.za> wrote:

> From: Enrico Goosen <eg...@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.


      

Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Enrico Goosen <eg...@metropolitan.co.za>.
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.


Re: @OneToMany/@ManyToOne, Bidirectional, Composite Key

Posted by Fay Wang <fy...@yahoo.com>.
Enrico,

    What is the primary key field in the TblScmpdt entity? Did you set primary key for tblScmpdt before calling merge? I made an integer primary key field in TblScmpdt, and set the primary key to 1 in tblScmpdt before calling merge, and your test code works fine for me (I also omit TblPdtbnfcde in your test code for lack of detailed information). If you already set the primary key and still get the error, please specify more detail of your TblScmpdt class.     
 

-f

--- On Thu, 6/12/08, Enrico Goosen <eg...@metropolitan.co.za> wrote:

> From: Enrico Goosen <eg...@metropolitan.co.za>
> Subject: @OneToMany/@ManyToOne, Bidirectional, Composite Key
> To: users@openjpa.apache.org
> Date: Thursday, June 12, 2008, 7:24 AM
> I can't get cascading persist working on my entities
> which have the following
> mappings.
> 
> TblScmpdt.java //Parent
> @OneToMany(fetch =
> FetchType.LAZY,mappedBy="tblScmpdt",cascade={CascadeType.MERGE,CascadeType.REMOVE})
> private Collection<TblPdtbnf> tblPdtbnfs = new
> ArrayList<TblPdtbnf>();
> 
> TblPdtbnf.java //Child
> @Id
>     @Column(name = "PDTBNF_ID",nullable=false)
>     private Integer pdtbnfId;    //Foreign key to
> TblPdtbnfcde.java
> 
>     @Id
>     @Column(name = "SCMPDT_ID",nullable=false)
>     private Integer scmpdtId; //Foreign key to
> TblScmpdt.java
> 
>  @ManyToOne(fetch =
> FetchType.LAZY,cascade=CascadeType.MERGE)
>     @JoinColumn(name =
> "SCMPDT_ID",referencedColumnName="SCMPDT_ID")
> 
>     private TblScmpdt tblScmpdt;
> 
> --------------------------------------
> 
> Here's the test code:
> 
> em.getTransaction().begin();
> 			
> 			TblScmpdt tblScmpdt = new TblScmpdt();
> 			tblScmpdt.setAdmsysCde("EBSTA");
> 			tblScmpdt.setFndCde("1526");
> 			tblScmpdt.setGccCde("A1526");
> 			tblScmpdt.setPflcmnDte(new Date());
> 			
> 			TblPdtcde tblPdtcde = em.getReference(TblPdtcde.class,
> new Integer(121));
> 			TblPdtbnfcde tblPdtbnfcde =
> em.getReference(TblPdtbnfcde.class, new
> Integer(13));
> 			
> 			tblScmpdt.setPdtcdeId(tblPdtcde.getPdtcdeId());
> 			
> 			TblPdtbnf tblPdtbnf = new TblPdtbnf();
> 			tblPdtbnf.setCmnDte(new Date());
> 			tblPdtbnf.setPdtbnfId(tblPdtbnfcde.getPdtbnfId());
> 			tblPdtbnf.setTblScmpdt(tblScmpdt);
> 			
> 			tblScmpdt.addTblPdtbnf(tblPdtbnf);
> //			tblScmpdt.getTblPdtbnfs().add(tblPdtbnf);
> 
> 			tblScmpdt = em.merge(tblScmpdt);
> 			
> 			em.getTransaction().commit();
> 
> ----------------------------------
> 
> The exception:
> 
> Caused by: <openjpa-1.0.0-r420667:568756 fatal user
> error>
> org.apache.openjpa.persistence.InvalidStateException:
> Attempt to set column
> "TBL_PDTBNF.SCMPDT_ID" to two different values:
> (null)"null", (class
> java.lang.Integer)"700" This can occur when you
> fail to set both sides of a
> two-sided relation between objects, or when you map
> different fields to the
> same column, but you do not keep the values of these fields
> in synch.
> 	at
> org.apache.openjpa.jdbc.sql.PrimaryRow.setObject(PrimaryRow.java:338)
> 	at
> org.apache.openjpa.jdbc.sql.RowImpl.flushJoinValues(RowImpl.java:289)
> 	at
> org.apache.openjpa.jdbc.sql.RowImpl.flushForeignKey(RowImpl.java:222)
> 	at
> org.apache.openjpa.jdbc.sql.RowImpl.setForeignKey(RowImpl.java:197)
> 	at
> org.apache.openjpa.jdbc.sql.PrimaryRow.setForeignKey(PrimaryRow.java:172)
> 	at
> org.apache.openjpa.jdbc.meta.ValueMappingImpl.setForeignKey(ValueMappingImpl.java:317)
> 	at
> org.apache.openjpa.jdbc.meta.FieldMapping.setForeignKey(FieldMapping.java:966)
> 	at
> org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy.insert(RelationFieldStrategy.java:207)
> 	at
> org.apache.openjpa.jdbc.meta.FieldMapping.insert(FieldMapping.java:555)
> 	at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.insert(AbstractUpdateManager.java:203)
> 	at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.populateRowManager(AbstractUpdateManager.java:145)
> 	at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:85)
> 	at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:72)
> 	at
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:514)
> 	at
> org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
> 	at
> org.apache.openjpa.datacache.DataCacheStoreManager.flush(DataCacheStoreManager.java:544)
> 	at
> org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
> 	... 9 more
> 
> -- 
> View this message in context:
> http://www.nabble.com/%40OneToMany-%40ManyToOne%2C-Bidirectional%2C-Composite-Key-tp17801245p17801245.html
> Sent from the OpenJPA Users mailing list archive at
> Nabble.com.