Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Circular references with identity id - what's the right way?
Circular references with identity id - what's the right way? [message #693883] Thu, 07 July 2011 12:44
Brendan Healey is currently offline Brendan Healey
Messages: 12
Registered: May 2010
Junior Member
I've had a good look around but can't see anything definitive about how to do this
so any help would be appreciated (no doubt I've missed something but I tried).

I've got two entities with a circular reference, each using identity id columns.
In this case I'm working with detached entities from JSF managed beans using
container managed persistence (@PersistenceContext). I've got some simple EJB
methods which just call EntityManager merge() and persist() methods.

My problem is that sometimes, and only sometimes, do I get an integrity constraint
violation exception on the line below marked ***. I see the sequence of events
like this:

1. EntityManager.persist() is called on a new Plog() within a transaction which
commits, NO flush or refresh.

2. Instantiate new Tlog(), setup link from this to the Plog from step 1 and
persist this within a transaction which commits. Again no flush or refresh.

3. Do some work which modifies the Tlog instance from step 2, merge these
changes into the persistent context taking care to return the latest version
after the merge (else OptimisticLockException).

4. At this point the Tlog has a reference to the Plog. Now setup a reference
from the Plog to the Tlog we just persisted. When I try to merge this change
(ejb.merge(plog)) sometimes, and only sometimes, I get an integrity constraint
violation (error code 1452) for the foreign key in the plog table which
references the id of the tlog table.

If this description is confusing I apologise, please just have a look at the code
below.

So question 1) why is it working sometimes and not others? I was testing away
happily yesterday, turn off the computer, get up in the morning and I'm getting
the exception?

2) why does it seem to work reliably one way but not the other, i.e. I never
have a problem setting up the link from the tlog to the plog, only the other
way round, despite using the exact same mechanism.

3) I gather that identity columns may not be the best generation method to use
in this scenario, would a table or sequence strategy be a magic bullet?

4) I'm not explicitly using flush(), refresh() or both, should I be? if so,
why doesn't it always not work?

I read somewhere that with a circular reference the persistence provider does
a shallow insert, so I'm using nullable = true on the @JoinColumn, but this
is the default so I don't suppose this is going to make any difference.

After I call my ejb.persist() method I can always output the id of the newly
persisted entity in debug output, so it's then confusing to get the constraint
violation.

@Entity
@Table(name = "plog")
public class Plog implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;
    @Version
    @Column(name = "version")
    private Integer version;
    @OneToOne
    @JoinColumn(name = "tlog", referencedColumnName = "id", nullable = true)
    private Tlog tlog;
    //getters & setters removed


@Entity
@Table(name = "tlog")
public class Tlog implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;
    @Version
    @Column(name = "version")
    private Integer version;
    @OneToOne
    @JoinColumn(name = "plog", referencedColumnName = "id", nullable = true)
    private Plog plog;
    //getters & setters removed


@EJB private MyEjb ejb;
Plog plog = new Plog();
ejb.persist(plog); // just calls EntityManager.persist()
Tlog tlog = new Tlog();
tlog.setPlog(plog);
ejb.persist(tlog);
// do some work, changes tlog
tlog = ejb.merge(tlog); // returns newly merged entity
plog.setTlog(tlog);
ejb.merge(plog); // *** integrity constraint violation here - sometimes!


EclipseLink 2.3
Glassfish 3.1
MySQL 5.5.12 with InnoDB

Thanks for any help,
Brendan.

[Updated on: Thu, 07 July 2011 15:44]

Report message to a moderator

Previous Topic:Stuck with Moxy getting started example
Next Topic:(no subject)
Goto Forum:
  


Current Time: Sat Sep 20 22:04:59 GMT 2014

Powered by FUDForum. Page generated in 0.01557 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software