geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeremy Boynes <jer...@coredevelopers.net>
Subject Re: Automatic Key Generation / Getting Involved
Date Wed, 31 Dec 2003 17:36:27 GMT
Brendan W.McAdams wrote:

> I take it the CVS for that resides @ OpenEJB also  

Yes

> 
> Thinking about what is done and how, I'm inclined to agree now on this  
> point.  Here's the big question:
> 
> Assuming the development efforts were willing to go in the direction of  
> supporting this functionality, taking a general poll - is it better  
> when dealing with things like supporting DB Generated keys to have a  
> 'generic methodology' which is by definition less flexible (like what  
> JBoss does), or a database specific support  structure that relies upon  
> coding a driver for each database type (Like BEA Weblogic does)?  As  
> much as it annoys me, my leaning is towards DB Specific support, with  
> an optional 'generic' for unsupported DBs.  Using each databases  
> functionality for a feature like this gives you the most flexibility,  
> and I can speak from experience that DBAs really consider it A Good  
> Thing (tm) when you use DB specific features, and allow the database to  
> manage key generation Angry Marauding DBAs == bad].
> 

If you look at JBo$$ then they have a generic framework for plugging in 
vendor-specific implementations (the entity-commands). I rewrote most of 
that back in May for the 3.2.2 release so the (crap) code is mine but 
please be very careful with the IP issues.

>> There are a few basic techniques that need to be covered:
>> 1) pre-insert generation. This might just be other implementations
>>    of o.o.n.entity.cmp.PrimaryKeyFactory that generate a PK somehow,
>>    inject it into the InstanceData and return the value. Examples
>>    could be a caching hi-lo key generator or something that issued
>>    a JDBC operation to get the value
> 
> 
> I think if we go along the lines of database specific drivers, this is  
> not the way to go.  

You need both. The issue is not about using the database but of when you 
  obtain the primary key value.

Some people want custom code - like your example of calling a stored 
procedure but have the container do it. This means work needs to be done 
before hand so the value is ready as insert time. A common scenario here 
  is Oracle where people want to SELECT FROM DUAL/INSERT rather than use 
INSERT RETURNING.

This is also exactly how EJB works if you are not using an unknown pk - 
it is just the code is contained in ejbCreate and sets up the values in 
cmp-fields. So you have to support this mechanism for known keys, it is 
trivial to extend for key generation.

> 
>>
>> 2) insert-side effect, where the value is generated as a consequence
>>    of performing the insert operation. Examples would be a MySQL auto-
>>    increment, JDBC getGeneratedKeys(), or Oracle with INSERT-RETURNING.
>>    The simple solution (KISS) is to always insert between ejbCreate and
>>    ejbPostCreate but that can mean some transactions insert then
>>    immediately update; the more complex solution would be to defer the
>>    insert for as long as possible, but that means being able to cope
>>    and reference to an EJB whose identity is not known. A compromise
>>    would be to delay until after ejbPostCreate which at least gives the
>>    user the chance to initialize any CMRs. This should be selectable by
>>    simply defining alternative VOPs for the create.
>>
> 
> This is absolutely, IMNSHO the best route to go.  

As I said, I think you need both.

<snip/>
> I see two primary methods:
> 
> 1) Something similar to JBoss' "unknown-pk" method - essentially,  
> declare that the primary key will be database generated, and that it is  
> a field of type 'X'.  There then could be a section in the  
> geronimo-cmp-rdbms.xml that declares a block of SQL or functions that  
> must be called post-insert to find out the generated key.  I'm not sure  
> however just how 'optimal' this could be.
> 
> 2) The Weblogic route.  Declare in the geronimo-cmp-rdbms.xml file that  
> the primary key is auto-generated on insert, and give specifics on what  
> the database is.  This would require of course that we have drivers for  
> the major RDBMs, and document how to setup and interface their key  
> generation methods within the CMP descriptors.  Albeit less generic, I  
> think this is the best route personally - I'm not sure I have enough  
> experience to make that declaration however.
> 

 > Mind pointing me in the right direction on this?

The EJB spec defines "unknown pk" as any EJB where the prim-key-class is 
java.lang.Object. It has to be generic as the app doesn't know what type 
of key the container will generate (int, Timestamp, String, ...) JBo$$ 
adds stuff that allows you to override the values set by the bean in 
ejbCreate (or not set) but IMO that is bogus - if the bean set a value 
then that should be the one used, but at that point the app knows the type.

The simplest approach would be to have the deployer choose which VOP 
impl to use for the create method and have a config option on that VOP 
which says which impl of PrimaryKeyFactory to use. The choice of VOP 
allows you to configure pre-insert or insert-side-effect approaches, and 
the choice of factory impl allows you to choose a key generation 
strategy (either generic, vendor-specific, or even application supplied 
code).

I would start by having a look at the CMPContainer and 
CMPOperationFactory impls in OpenEJB - there are two create VOPs 
already. I would also recommend starting with the code and work out what 
you need to have the deployer build (IoC remember), and only at the end 
define the XML needed by the deployer.

-- 
Jeremy

/*************************
  * Jeremy Boynes
  * Partner
  * Core Developers Network
  *************************/

Mime
View raw message