Search code examples
javasqlderbyhsqldb

Solving an exclusive relationship in a java embedded SQL database


I'm trying to build a java program that needs to store data in a SQL database which needs to be embedded in my application so I can carry out the app to any PC and the data persists.

Then, my paradigm is the following.

MAIN TABLE has four relationships with four tables. All of them are (0:N) on each side, so an example would be:

MAIN_TABLE (0:n) ------ (0:n) TABLE_1

The same for TABLE_2, TABLE_3 and TABLE_4 giving an example.

Until here all is OK, the problem comes when "Main_Table" ONLY could have ONE relationship, being with "table_1" OR "table_2" OR "table_3" OR "table_4". They cannot never be two or more of them. To solve the N:M relationships, the tables "alpha", "beta", "gamma" and "lambda" come in, one handling the relationship of each TABLE_X with MAIN_TABLE.

Some people told me to use triggers that checks if a row on MAIN_TABLE already has a relationship with the three other tables, and if true, abort the insert, something like this:

DELIMITER $$
CREATE TRIGGER checker1
BEFORE INSERT ON alpha
FOR EACH ROW
BEGIN
  DECLARE count INTEGER;
  SELECT count(MAINTABLEid) INTO count FROM beta WHERE beta.MAINTABLEid= NEW.MAINTABLEid;
  IF count > 0 THEN SIGNAL SQLSTATE '45000' SET message_text = 'THE ROW IS ALREADY CONNECTED TO ANOTHER TABLE.';
  END IF;
  SELECT count(MAINTABLEid) INTO count FROM gamma WHERE gamma.MAINTABLEid= NEW.MAINTABLEid;
  IF count > 0 THEN SIGNAL SQLSTATE '45000' SET message_text = 'THE ROW IS ALREADY CONNECTED TO ANOTHER TABLE.';
  END IF;
  SELECT count(MAINTABLEid) INTO count FROM lambda WHERE lamba.MAINTABLEid= NEW.MAINTABLEid;
  IF count > 0 THEN SIGNAL SQLSTATE '45000' SET message_text = 'THE ROW IS ALREADY CONNECTED TO ANOTHER TABLE.';
  END IF;
END;$$
DELIMITER ;

I tried using Derby and HSQL, but both of them doesn't support the "DELIMITER" command, and without changing the delimiter it's impossible to save a trigger as it encounters a semicolon the process stops.

Which DB could I use to solve this, or how can I do it with Derby or HSQL? My program will be written in Java and the Database should control almost all situations.

Thank you in advance.


Solution

  • After a lot of research, I determined that I need to use HSQLDB for two main reasons: Derby only allows triggers with only one sql query. And the second reason avoids creating a sequence of triggers as Derby also doesn't allow any declare clause. HSQLDB allow all of this, and by the way, the trigger sentence on HSQLDB would be as this:

    create trigger triggerName before insert on alpha
        referencing new row as nuovo
            for each row
                begin atomic
                    declare varCount int;
                    set varCount=(select count(beta.MAINTABLEid) from beta where beta.MAINTABLEid=nuovo.MAINTABLEid);
                    if varCount>0 then signal sqlstate '45000' set message_text='The row is already referenced.';
                    end if;
    --repeat SET and IF lines to check gamma and lambda tables
                    end