Reputation: 4973
In my application I have a component that receive objects from another components and insert them to MySQL DB. Currently I'm buffering the objects and once in a while (few seconds) the objects are inserted to the DB using a batch (using JDBC, not hibernate).
I would like to break this objects to 2 objects, then two buffers, and finally insert them to 2 different tables.
My first thought was to use MySQL auto generated ID to tie the two sub-objects together in the table (as foreign key).
My problem is - how will I know the auto-generated ID for the 'father' object when I insert the 'child' object?
My ideas are:
LAST_INSERT_ID();
What do you think?
Upvotes: 1
Views: 2663
Reputation: 108954
The standard interface with JDBC to retrieve generated keys is to use the getGeneratedKeys()
method on the statement. See Example 21.8. Connector/J: Retrieving AUTO_INCREMENT column values using from the MySQL site
Upvotes: 0
Reputation: 14901
Your essential problem is that you need information from the database for one object before you can store the other object.
Let's say you split your compound object into two smaller objects, namely Place and Map.
If you must have two buffers to store Place and Map, then I see three ways of doing so:
Put only Place in the store-buffer. When Place is stored, and the PK has been read from the database, ONLY THEN place Map in the other store-buffer.
Put Place and Map in their own store-buffers. When a Map is about to be stored, check it's associated Place, to see if the PK has been generated yet. If it has, then store the Map. If it hasn't, then skip that Map and check the next Map.
Put Place in the store-buffer. When it gets stored, read the PK, and immediately store the Map also. This obviously does not use two store-buffers.
Look at how other objects are stored in your application. Certainly they don't generate their own IDs before they are stored in the database. Certainly you don't try to put them in a store-buffer before you have all the information necessary to store them. My recommended course of action is therefore option 1 or 3.
Upvotes: 0
Reputation: 36630
Maybe this helps (you can use LAST_INSERT_ID() also in plain SQL, not only inside procedures),see also http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html:
INSERT INTO foo (auto,text) VALUES(NULL,'text'); # generate ID by inserting NULL
INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); # use ID in second table
Given that the OP runs the INSERTs on separate threads, the IDs need to be preallocated - you can use a sequence to safely select unique IDs (see also MySQL information functions):
Create a table to hold the sequence counter and initialize it:
mysql> CREATE TABLE sequence (id INT NOT NULL);
mysql> INSERT INTO sequence VALUES (0);
Use the table to generate sequence numbers like this:
mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql> SELECT LAST_INSERT_ID();
Upvotes: 0
Reputation: 4137
Both approaches are valid.
The java approach is more DB agnostic, and might be easier for you to switch database or to support multiple DB vendors.
Upvotes: 0
Reputation: 2558
One solution would be to insert the two records in the same transaction as done in this question. JDBC: foreign key on PK created in same transaction
That is:
Upvotes: 1