I am playing with dropwizard and I want to build a REST application that has various foreign-key relations in the entities.
For example given the following 3 tables:
-- table persons CREATE TABLE PUBLIC.PERSONS( ID BIGINT DEFAULT NOT NULL AUTOINCREMENT, FIRST_NAME VARCHAR(255), LAST_NAME VARCHAR(255), BIRTHDAY DATE, ADDRESS_ID BIGINT NOT NULL, CREATED TIMESTAMP DEFAULT 'current_timestamp', MODIFIED TIMESTAMP ); ALTER TABLE PUBLIC.PERSONS ADD CONSTRAINT PUBLIC.PK_PERSONS PRIMARY KEY(ID); -- table customers CREATE TABLE PUBLIC.CUSTOMERS( ID BIGINT DEFAULT NOT NULL AUTOINCREMENT, PERSON_ID BIGINT NOT NULL, STATUS_CODE VARCHAR(100) DEFAULT 'ACQUISITION' NOT NULL, CREATED TIMESTAMP DEFAULT 'current_timestamp', MODIFIED TIMESTAMP ); ALTER TABLE PUBLIC.CUSTOMERS ADD CONSTRAINT PUBLIC.PK_CUSTOMERS PRIMARY KEY(ID); -- table addresses CREATE TABLE PUBLIC.ADDRESSES( ID BIGINT DEFAULT NOT NULL AUTOINCREMENT, LINE_1 VARCHAR(255), LINE_2 VARCHAR(255), ZIP VARCHAR(255), CITY VARCHAR(255), COUNTRY_CODE VARCHAR(3), PHONE VARCHAR(255), FAX VARCHAR(255), CREATED TIMESTAMP DEFAULT 'current_timestamp', MODIFIED TIMESTAMP ); ALTER TABLE PUBLIC.ADDRESSES ADD CONSTRAINT PUBLIC.PK_ADDRESSES PRIMARY KEY(ID); -- and following forign key constraints: ALTER TABLE PUBLIC.PERSONS ADD CONSTRAINT PUBLIC.FK_PERSON_ADDRESS FOREIGN KEY(ADDRESS_ID) REFERENCES PUBLIC.ADDRESSES(ID) ON DELETE SET NULL NOCHECK; ALTER TABLE PUBLIC.CUSTOMERS ADD CONSTRAINT PUBLIC.FK_CUSTOMER_PERSON FOREIGN KEY(PERSON_ID) REFERENCES PUBLIC.PERSONS(ID) ON DELETE SET NULL NOCHECK;
I have started to implement a customerDAO that reads the data of the customer table an dthe referenced tables with one SQL query, that was not very complicated:
@RegisterMapper(CustomerResultMapper.class) public interface CustomerDAO { @SqlQuery("select p.id as person_id, " + "p.first_name, p.last_name, p.birthday, " + "c.id as customer_id, c.status_code, " + "a.id as address_id, a.line_1, a.line_2, a.zip, " + "a.city, a.country_code, a.phone, a.fax " + "from customers c, persons p, addresses a " + "where c.id = :id " + "and c.person_id = p.id " + "and p.address_id = a.id") public Customer findCustomerById(@Bind("id") long id); }
(For the sake of brevity, I skip the mapper, since that is not my actual question)
Now I want to insert a new customer, I have all the required data, including the data which belongs in the referenced tables.
I could not find a way how to execute multiple queries with jdbi annotations, so I figured, I have to create a DAO method for every one of the tables and insert the data from within java, updating the foreign key references manually.
But also this does not work because I could not find a way to read the autogenerated ID value after an insert.
Any idea how I could approach this problem so I can keep the references correct?
Never mind, I found the solution in the meantime, at least how to get the auto generated key:
in your DAO, add the @GetGeneratedKeys annotation, make sure that your return value of the method matches the value of the generated key:
@SqlUpdate("insert into addresses (line_1) values ('address line 1')") @GetGeneratedKeys public long insertAddress();
In your resource then, you can simply use the return value:
long id = customerDAO.insertAddress(); System.out.println("Found id " + id);
This works to get the generated key for one statement, however in my case, I still need to make multiple queries and fill in the correct references manually.
Should anyone have an idea how I could simplify this process and let the references be filled in automatically, I still would be interested to hear about.
Thanks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With