It's not a secret anymore!*
The moose likes EJB and other Java EE Technologies and the fly likes valid PRIMARY_KEY EJB Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "valid PRIMARY_KEY EJB" Watch "valid PRIMARY_KEY EJB" New topic
Author

valid PRIMARY_KEY EJB

Balamaci Serban
Ranch Hand

Joined: Mar 16, 2005
Posts: 49
Hi ranchers! Seems like i'm stepping in cow s**t at every step with them here EJBs.
Look't what i've got here: So was minding my own bussiness trying to create some test EJBs when the problem hits me. You need to have a PRIMARY_KEY retuned with the ejbCreate method in an BMP EntityBean. So:

Well something could be wrong with this. From the concurent nature of beans, if say by chance, 2 of them get created at the same time, they would both be calling SELECT MAX(id) at the same time and seeing the same key available, but only one would be succesful at an INSERT. The normal thing to do in a casual class, i would simply set up a transaction with SERIALISED atribute to make sure that we would not obtain two PKs. However it Entity Beans you cannot use transactions.

I remember that one of the features with the kewl EJBs would be that we would not have to worry about accesing about the threading issues of simultaneus access to common resources. So I should not worry about the problem? Or i should move the SELECT in a SessionBean and start a transaction, do the SELECT, obtain the next key and pass it as a parameter to the create in the EntityBean and commit?
[ March 19, 2005: Message edited by: Balamaci Serban ]
Valentin Tanase
Ranch Hand

Joined: Feb 17, 2005
Posts: 704
Hi Serban,


Well something could be wrong with this. From the concurent nature of beans, if say by chance, 2 of them get created at the same time, they would both be calling SELECT MAX(id) at the same time and seeing the same key available, but only one would be succesful at an INSERT.

Correct.

The normal thing to do in a casual class, i would simply set up a transaction with SERIALISED atribute to make sure that we would not obtain two PKs. However it Entity Beans you cannot use transactions.

The second part of your affirmation (the bolded part) is correct: you cannot use BMT with entity beans. The first one is not quite true; you are allowed to set the transaction isolation level inside of your entity bean (calling the con.setTransactionIsolation method). However this is definitely not a very good practice, because changing the transaction isolation level in the middle of a transaction might issue an implicit commit.

I remember that one of the features with the kewl EJBs would be that we would not have to worry about accesing about the threading issues of simultaneus access to common resources.

You don�t need to worry about instance variables and therefore you don�t need to care about writing synchronized code. This is why the container pools the bean instances and associates an instance with exactly one execution thread. However you need to take care when accessing external resources like databases and this is actually the meaning of setting transaction isolation levels.

So I should not worry about the problem?

Yes you should.

Or i should move the SELECT in a SessionBean and start a transaction, do the SELECT, obtain the next key and pass it as a parameter to the create in the EntityBean and commit?

Actually your problem is not a new one. Check the net for primary key generation design patterns and you�ll get some good hints. Your intuition is correct, you need to find another way to generate your primary key. The truth is that this is not very intuitive (or at least it wasn�t for me). Just for argument sake let�s imagine that one uses the System.currentTimeMillis() to generate pk. Usually this could be done with an wrapper object that uses a synchronized block to assure the pk uniqueness. Looks just like the perfect solution. However this design will fail lamentably if the application will be deployed in a clustered environment. Therefore you might need a more robust design, like using database sequences for example. Ultimately you might turn to your container for help, since many container vendors provide automatic pk generation -that works only with CMP unfortunately :-(
Regards.


I think, therefore I exist -- Rene Descartes
Balamaci Serban
Ranch Hand

Joined: Mar 16, 2005
Posts: 49
Salut Valentin!
Well hell u were wright. The PK problem is just a huge problem. It's huge anyway if you want to obtain app serv. indep, database indep, and clustering. Just watch these guys talk about it http://theserverside.com/patterns/thread.tss?thread_id=220

Of course the solution i took is pretty bad because it always hits the database(although it works for clustered enviroments that have a common database) and needs to be syncronised in some way.

I'm thinking of somehow getting at first the MAX(id) and store it in a variable and keepit in cache. After that have a method getNextVal() that increments that value(would be syncronised if i use a common acces variable). Not really sure how would i keep it in memory(but...). When the server crashes or it thinks it needs to refresh the value, it would just have to take a trip to the database to see what's the max id value.

And there's the SELECT max(id) FOR UPDATE aproach that is the most simple and inneficient of them all because you just let the database take care of mutual exclusion of simultaneus acces, and i get a feeling this one would pretty much lock the whole table and make even a specific select * where id=3 wait.

Much more elegant solution that with SEQUENCES as you would just have to syncronise acces to the sequence and a specific select on the articles of the table would not have to wait. However a "select sequence.nextval from table" seems to be database specific pretty much(at least it won't work with mysql).

And there's the UUID and High/Low algorithm that i did not look through it. It seems like a solve all problems especially with clusters, only thing that it seems it deals with String PK(and to verify String equality in database when using a JOIN it seems to me like complete suicide).

Well Floyd Marinescu seems to have a whole chapter in his "Design Pattern"(which is free for download-I love these guys -) to discuss this, so we should go read this first. However I found myself lacking more basics stuff and if I go read all my "To be read books" i would never finish my project(so i'll just go for the first lame solutin i come across and worry about a more optimised PK generation after i see the bulk of the project finnished).

Well... Happy Coding .
[ March 21, 2005: Message edited by: Balamaci Serban ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: valid PRIMARY_KEY EJB
 
Similar Threads
Record Locking in multi-user
OrderBy with ElementCollection doesn't work
Get Updated Record
ICE 287 answers for WebSphere 5.0
Table-level locking, how?