|
Why does my Struts/BC4J application use two sequence numbers for every new row?
The situation is typically that you have written code like this in your entity object's create() method:
public void create() { super.create(); SequenceImpl s = new SequenceImpl("YOUR_SEQUENCE_NAME"); setYourPrimaryKeyAttrName( s.getSequenceNumber() ); }
which "eagerly" pulls a sequence number off of your database sequence named YOUR_SEQUENCE_NAME and assigns it as the default value of the YourPrimaryKeyAttrName attribute in your entity object.
When you render the JSP page that shows the empty "new" row to have the user "fill-in" BC4J creates a new row so that any entity-level default values (either declaratively defined or populated by your EO create() method) will show up automatically in the "new" record.
By pulling the sequence number in your create() method, you are going to get one number when you render the blank form, and then another number when that form is posted and inserted into the database. Here is the sequence of events.
- Render a blank row to create empty HTML form (with defaults)
- Creating a blank VO row creates a blank EO instance
- Your create() method pulls, say, sequence # 1001
- The user sees 1001 on the page, and fills out the form
- User submits
- New row is created (this time row is not just a blank row for defaults)
- Creating a blank VO row creates a blank EO instance
- Your create() method pulls, say, sequence # 1002
- FormBean data is copied to new row
- Since FormBean has 1001 in it, value 1001 gets committed but in the meantime, a second sequence number was used/wasted.
This is why using DBSequence and a trigger-assigned sequence number is best if you want to minimize gaps in the numbers. In that case, the BC4J framework assigns a temporary negative number to be your primary key value, and then refreshes this value at post/commit time with the actual database sequence value assigned by a BEFORE INSERT FOR EACH ROW database trigger.
|