> Hi,
>
> OK, my example was a bit simplistic. Artist and Cd were
> picked just as examples, this is not a real case, you can
> think of it as any ordinary 1:n relationship.
There's no absolutes when discussing caching & distributed systems.
The correct way to go is very much context dependant. This is a
disclaimer,
because different approaches are valid in certain contexts.
>
> >> Now, I would implement this so that the relationship fields
> >> (Cd.artist and
> >> Artist.cds) are lazy loaded.
> >
> >This implies that you're not caching anything. Transaction isolation
> >comes into play here as well. These are important details when
> >considering stale-data scenarios.
>
> In this example I'm assuming that there is caching of EJBs
> which is handled by container. And that the transaction is
> initiated by a call to session bean (session facade).
Super. EJB instances are cached.
What's the caching schema?
Relationships are lazy-loaded. How?
You load the PK's for the relationships lazily?
You have a special Collection implementation that loads the EJBs lazily?
Both?
>
> >> Calling set() -methods would
> >> update both the object and the parameter object, ie.
> >> bornInTheUsa.setArtist
> >> (bruceSpringsteen) would update both bornInTheUsa.artist field AND
> >> bruceSpringsteen.cds collection (otherwise
> bruceSpringsteen will have
> >> invalid state after the call).
> >
> >Not necessarily. It would have an invalid state after the
> transaction
> >finishes, if it's not voted that it should rollback. I
> mention this so
> >that you're aware that in other methods within the same TX
> the inserted
> >relationship *may* not show. Again, TX isolation comes into play as
> >well.
>
> I'm sorry, I did not quite get that. Do you mean that, if I create cd.
> setArtist() method like:
>
> Cd {
> setArtist(Artist artist) {
> Artist previousArtist = this.artist;
> this.artist = artist;
> this.artistLoaded = true;
>
> // make sure that artist EJBs reference the right cd EJB
> artist.addCd(this);
What's that? You can't pass 'this' there. Pass the PK or the handle.
Bear in mind that if you execute this code:
Artist {
addCd(Cd cd) {
cdList.add(cd.getPrimaryKey() );
}
}
You'll need to mark the bean as reentrant.
> if (previousArtist != null) {
> // the old artist no longer has this cd
> previousArtist.removeCd(this);
> }
> }
> }
No, within the same stack it'll work as the data still is in memory.
When beans are passivated and the TX isn't committed you might
experience problems. This is specially true if you have the EJBs
distributed or you're using the Remote interfaces.
On top of that, depending on caching schemes and/or commit options, the
calls to ejbStore may be deferred:
>
> And call it from session bean like:
>
> // user changed some record's artist
> Artist newArtist = artist.findByPrimaryKey(newArtistIdFromUser);
> Cd editedCd = cd.findByPrimaryKey(cdIdFromUser);
> editedCd.setArtist(newArtist);
>
> either editedCd or newArtist could have invalid state after
> setArtist(); ?
The invalid state would be transient, until the TX is committed.
Concretely, I meant:
Cd {
addArtist(Artist artist) {
add(artist);
artist.addCd(this.getPrimaryKey() );
}
}
SessionBeanMusicManager {
addCDandArtist(String cd, String artist) {
Cd c = cdHome.create(cd);
Artist a = artistHome.create(artist);
c.addArtist(a);
//do something here..
Artist b = artistHome.findFirstByName(artist); //a and b
should be the same.
Collection col = b.getCDs(); //the collection is empty
}
}
This may ocurr as well(has happened to me a number of times). Demarking
Cd.addArtist() as REQUIRES_NEW "fixed" the problem, leaving me to clean
up manually if anything went wrong (yeah... I know, not nice. I
compromised).
>
> What I am trying to accomplish here is nice automatic
> relationship handling a la CMP CMR but with BMP. I am aware
> that it is probably not the easiest route, but this is for
> testing / education purposes.
I also take it that you're planning to use Remote interfaces. That's the
whole problem. With local interfaces the container can make certain
assumptions that will allow for complete consistency without huge
performance penalties.
Essentially it boils down to these situations that the container must
handle somehow:
You're using Remote interfaces (so calls and lookups may come from
anywhere).
When do you issue the ejbStore call? Right away, at certain intervals,
at the end of the transaction?
If you fire it before the transaction commits, how does your database
rollback segment behave?
If caching is enabled, when will cached instances on other servers be
updated?
>
> >> Is this the right way to go? Plus, can I trust that in clustered
> >> environment also EJB's in other instances are updated?
> >> So that there is not an invalid artist bean in some
> >> instance having bruceSpringsteen.cds missing the bornInTheUsa?
> >
> >As long as you don't cache the entities(and make sure the container
> >doesn't do it for you either), yes you can trust. As a sidenote, I'd
> >monitor performance if there's no caching at all.
>
> So, with caching, I cannot trust that the relationships of
> all instances are valid?
Unless you roll out your own distributed resource coordinator and it can
cooperate
with the app server's one, no, I'd say you can't trust.
I'd disable the caching altogether for this very wicked special case.
My 2c,
JP
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".