#UniqueConstraint requires alter table in MariaDB if table already existed before with no constraints? - spring

I apologize if I repeat the question, but I did not find a similar one.
I have added a unique constraint on an already existent table. We use MariaDB.
I have used the annotation:
#Table(uniqueConstraints={#UniqueConstraint(name="autonomy_name_energyType", columnNames={"autonomy","name","energyType"})})
The unit tests pass, but in the DB I am still allowed to create duplicates.
Do I need an ALTER table too? By checking the table I can see there are no constraints added to it.
Thanks

As explained in these SO posts :
Unique constraint not created in JPA
#Column(unique=true) does not seem to work
An explicit alter table query is needed for ur constaints to take effect on the db level.
As an extra info, it would have worked if the table was being re-created via JPA. see :
Add a unique constraint over muliple reference columns

Related

Spring Boot: How do I specify execute order of different schema.sql files?

I have created a table that has a foreign key constraint on spring-session-jdbc's spring_session table. The main motivation is that spring-session would delete the rows so that it would cascade and delete entries associated with the actual session. It became a "only works on my machine" problem because only me have had the table already in place when I start the development server. It would only work if others comment out the table first, initialize the server, then revert and do it again. Otherwise, nested exception is java.sql.SQLException: Failed to open the referenced table 'spring_session'.
I think the solution is to specify the run order of (or dependencies between) the initialization sql files. I cannot find that setting after some searching, so I am here.
schema.sql:
drop table if exists foo;
create table if not exists foo (
sid char(36) not null,
foreign key (sid) references spring_session (session_id) on delete cascade,
-- other columns and constraints
);
Possible workarounds:
Workaround #1: put an alter table add constraint statement like this in data.sql.
Workaround #2: grab spring-session-jdbc's schema.sql and put it into my schema.sql, then set spring.session.jdbc.initialize-schema=never in application.properties.
U can try flyway,it can manage your init sql files by giving them a version number. And it can record which sql have been executed, so if add another sql files, it will excute the sql you added, pass the others that have been executed.

What is the purpose of #Update's OnConflictStrategy in Room?

I understand why setting an OnConflictStrategy for an #Insert annotation makes sense -- if the client is inserting a record that already exists, the database configuration needs to know how to reconcile that situation.
But I don't understand what it means to set an OnConflictStrategy on an #Update annotation. Isn't the idea of #Update to necessarily expect a row in the database that already exists, and then update it? Is that considered a "conflict"?
It is rather about constraints, not about records that already exists.
For example, let's imagine table A which has foreign key that connects this table records with records from another table B.
If we will update foreign key value in table A with the value which does not exist in table B then we will violate constraint because in such case there are will be records in table A which does not relate to any records from table B.

Inserting in a child table

The design of my database has a table named person and tables employee and student are specializations of the table person the relationship between tables is total and has an overlapping restriction.
The problem is that I want to insert a student or employee and that the parent table (person) is updated automatically but the DBMS says violated a referential integrity constraint
I am using oracle can someone help me?
If I understood you correctly you have one table per type (TPT) and an employee can never be a student and also the other way around.
I assume that your problem is that the constraint is checked immediately instead of using deferred checking. That means the constraints are checked when your transaction is finished - which gives you the possibility to insert an employee/student and let your trigger do its work and after that do the commit.
Information about deferred constraints:
Oracle documentation
More information

Create constraint in alter table without checking existing data

I'm trying to create a constraint on the OE.PRODUCT_INFORMATION table which is delivered with Oracle 11g R2.
The constraint should make the PRODUCT_NAME unique.
I've tried it with the following statement:
ALTER TABLE PRODUCT_INFORMATION
ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (PRODUCT_NAME);
The problem is, that in the OE.PRODUCT_INFORMATION there are already product names which currently exist more than twice.
Executing the code above throws the following error:
an alter table validating constraint failed because the table has
duplicate key values.
Is there a possibility that a new created constraint won't be used on existing table data?
I've already tried the DISABLED keyword. But when I enable the constraint then I receive the same error message.
You can certainly create a constraint which will validate any newly inserted or updated records, but which will not be validated against old existing data, using the NOVALIDATE keyword, e.g.:
ALTER TABLE PRODUCT_INFORMATION
ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (PRODUCT_NAME)
NOVALIDATE;
If there is no index on the column, this command will create a non-unique index on the column.
If you are looking to enforce some sort of uniqueness for all future entries whilst keeping your current duplicates you cannot use a UNIQUE constraint.
You could use a trigger on the table to check the value to be inserted against the current table values and if it already exists, prevent the insert.
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm
or you could just remove the duplicate values and then enfoce your UNIQUE constraint.
EDIT: After Jonearles and Jeffrey Kemp's comments, I'll add that you can actually enable a unique constraint on a table with duplicate values present using the NOVALIDATE clause but you'd not be able to have a unique index on that constrained column.
See Tom Kyte's explanation here.
However, I would still worry about how obvious the intent was to future people who have to support the database. From a support perspective, it'd be more obvious to either remove the duplicates or use the trigger to make your intent clear.
YMMV
You can use deferrable .
ALTER TABLE PRODUCT_INFORMATION
ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (PRODUCT_NAME)
deferrable initially deferred NOVALIDATE;

Linq insert with no primary key

I need to insert records into a table that has no primary key using LINQ to SQL. The table is poorly designed; I have NO control over the table structure. The table is comprised of a few varchar fields, a text field, and a timestamp. It is used as an audit trail for other entities.
What is the best way to accomplish the inserts? Could I extend the Linq partial class for this table and add a "fake" key? I'm open to any hack, however kludgey.
LINQ to SQL isn't meant for this task, so don't use it. Just warp the insert into a stored procedure and add the procedure to your data model. If you can't do that, write a normal function with a bit of in-line SQL.
Open your DBML file in the designer, and give the mapping a key, whether your database has one or not. This will solve your problem. Just beware, however, that you can't count on the column being used for identity or anything else if there isn't a genuine key in the database.
I was able to work around this using a composite key.
I had a similar problem with a table containing only two columns: username, role.
This table obviously does not require an identity column. So, I created a composite key with username and role. This enabled me to use LINQ for adding and deleting entries.
You might use the DataContext.ExecuteCommand method to run your own custom insert statement.
Or, you might add a primary key to a column, this will allow the objects to be tracked for inserts/updates/deletes by the datacontext. This will work even if the column isn't really an enforced primary key in the database (how would linq know?). If you're only doing inserts and never re-use a primary key value in the same datacontext, you'll be fine.

Resources