Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] OneToOne relation with PrimaryKeyJoinColumn: no writing?

Hello Andrei,

Using the PrimaryKeyJoinColumn tells the OneToOne mapping that the foreign key is the Id field for this entity and that it should be read only - since the ID is set though Transaction's urn attribute. It does not change how the OneToOne mapping behaves with respect to foreign keys and reference keys; it will not use the foreign key value if the target key is not set as you are expecting. Using the mappings you have defined, TransStatus is completely independent of Transaction and needs to have its urn attribute populated before it can be persisted. You will either need to manually set the transStatus.urn value after it has been assigned to the Transaction ie:
 Transaction trans = new Transaction();
 em.persist(trans);
 em.flush();

 TransStatus transStatus = *new* TransStatus();
 trans.setStatus(transStatus);
 transStatus.setUrn(trans.getUrn());
 em.getTransaction().commit();

Or you can add a relationship from TransStatus to Transaction to set the value for you. In JPA 1.0, the TransStatus requires two mappings:

 public class Transaction {
 @Id
 @Column(name="URN", insertable=false, updatable=false)
 private int urn;
@OneToOne(cascade=CascadeType.ALL)
 @JoinColumn(name="URN")
 private Transaction trans;

Or if using JPA 2.0 draft (implemented in EclipseLink 2.0), it allows OneToOne fields to define the id, making the urn attribute in TransStatus redundant:
 public class Transaction {
 @Id
 @OneToOne(cascade=CascadeType.ALL)
 @JoinColumn(name="URN")
 private Transaction trans;

This relationship will need to be set before TransStatus is persisted for the id to be set, but the Transaction->TransStatus relation can either be removed or marked as mappedby this new relationship.


Best Regards,
Chris


Andrei Shakirin wrote:
Hi,
Could you please help me with a issue regarding OneToOne relation with PrimaryKeyJoinColumn?
The problem is that it seems to work only for read, not for write.
Consider the following sample: @Entity
@Table(name="TRANS", schema="TEST")
*public* *class* Transaction {
@Id @GeneratedValue(strategy=GenerationType./SEQUENCE/, generator="CUST_SEQ")
        *private* *int* urn;
@OneToOne(cascade=CascadeType./ALL/) @PrimaryKeyJoinColumn
        *private* TransStatus transStatus;
}
@Entity
@Table(name="TRANSSTATUS", schema="TEST")
*public* *class* TransStatus {
@Id
        *private* *int* urn;
}
Transaction trans = *new* Transaction();
TransStatus transStatus = *new* TransStatus();
trans.setStatus(transStatus);
em.getTransaction().begin();
em.persist(trans);
em.getTransaction().commit();
By commit EclipseLink makes two inserts:
INSERT INTO TEST.TRANSSATUS (URN) VALUES (?)
[0]
INSERT INTO TEST.TRANS (URN) VALUES (?)
[234]
I expect that primary key generated for Transaction will be automatically used for TransStatus, but it not the case - it is always set to 0. If I remove CascadeType.ALL and save objects with two persist calls, it works fine by reading.
Is it design behaviour or I do something wrong?
Unfortunately I cannot use @SecondaryTable with inner join here, because there are some old transactions without status and I should get them by find also. Reagrds,
Andrei.
------------------------------------------------------------------------

_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users


Back to the top