Hi Phil,
I've made some modifications to this procedure that go in the direction
you were suggesting in your points 1,2 and 3 and I had a good improvement.
> You've also said nothing about how you will be determining the id for the persistant book associated with the current annotation.
I assume that the pair of attributes (AUTHOR, TITLE) of the relation
BOOK is unique (actually the db is more complex than that but this was a
significant simplification). So I query BOOK with two values for this
pair of attributes, e.g.:
select *
from BOOK " +
where AUTHOR = ? and TITLE = ?
> You've also said nothing about determining that an annotation you are processing already exists in the annotation table. (It's possible that all annotations are considered new and get a new row in their table.)
Yes, that's exactly the case. All annotation are considered new and get
a new row.
> Is a sequence appropriate? Would identity columns for BOOK and ANNOTATION be an alternative?
In the new procedure I cannot use identity columns.
The new procedure works as follows:
1. Query the table BOOK to determine the ids of the books that are
already persistent. To do that I execute a PreparedStatement for each
book:
String query = "select * " +
"from public.BOOK " +
"where AUTHOR = ? and TITLE = ?";
preparedStatement = connection.prepareStatement(query);
for each book
preparedStatement.setXXX(1,...);
preparedStatement.setXXX(2,...);
resultSet = preparedStatement.executeQuery();
As you suggested in point 1, I tried to execute a multiple statement
(using addBatch) with a preparedStatement but it is not supported with a
SELECT.
2. Request as many ids as needed for the annotations from the sequences
that manages the ANNOTATION table id:
preparedStatement = connection.prepareStatement("values nextval for
public.annotation_id_seq");
for each annotation
ResultSet resultSet = preparedStatement.getResultSet();
3. Request as many ids as needed for the books.
4. Inserts tuple in ANNOTATION table.
5. Inserts tuple in BOOK_ANNOTATION table.
6. Insert tuples in BOOK table.
Points 4,5 and 6 are implemented through a prepared statement batch
(what you called in your point "multiple statement", if I got it right).
As an example, consider point 4:
String sql = "insert into public.annotation(id,author,text) " +
"values(?,?,?);";
preparedStatement = connection.prepareStatement(sql);
for each annotation
preparedStatement.setXXX(1,...);
preparedStatement.setXXX(2,...);
preparedStatement.setXXX(3,...);
preparedStatement.addBatch();
This is analogous to what I intended to do for point 1. But apparently
multiple sql commands with prepared statements don't work with SELECTs.
Thanks a lot!
Diego