SchemaExport, NHibernate and deleting foreign keys - nhibernate

I am building my mapping and then using schema export to update my DB. However, if I delete an association in my mapping, since it's no longer in the mapping, when I run SchemaExport, it will not delete the foreign key for the deleted association. This means that it then fails to drop the table associated with that foreign key. Which further means that it can't recreate the table and I get a "There is already an object named Foo in the database" exception. Is there any way to brute delete the table via Schema Export?

The cleanest way is to do SchemaExport.Drop with the old nhibernate configuration, then create with the new one.
Alternatively you could drop and recreate the database itself, here's an example which does this at file level for SQL Server Express: http://nicholas.piasecki.name/blog/2010/01/integration-testing-with-sql-server-express-2008-nhibernate-and-mstest/

Related

Foreign key relationship can't be created (SQL Server)

I created a SQL Server database first (2 tables) and then tried to load data through SSIS data flow task. At the last step an error has occurred.
When I remove a relationship between two tables in the database, the SSIS task is completed successfully and the data is loaded! But, after I load data into the tables, I can't create relationship between them.
Based on this you can conclude that a relationship can be created when there is no data in a table. Just to mention, data types are the same in both tables.
How could I work out a solution?
Thank you!
It seems the error in SSIS is due to a foreign key violation. The purpose of the foreign key relationship is to prevent you for loading bad data. When you loaded without the FK, you inserted bad data and cannot create a (trusted) foreign key constraint afterward.
The solution is to either fix the source data or modify your package to avoid inserted data that doesn't exist in the referenced table. The latter can be done with a lookup task, sending found rows down the happy path to the target table. You could either ignore not found rows or write those to an error table or file.

SQL Server 2016 Cannot add system versioning to relationship table

The SQL Server 2016 system versioning is cool. I am using the free Developer version. Thanks MS!
I am unable to figure out if it will give me versioning of many to many relationships. I have a User object that has a collection of Roles and vice versa. Entity Framework has generated the UserRoles table that holds the relationship between User and Roles. I was able to turn on system versioning for the User and Roles tables using this article http://sqlhints.com/tag/modify-existing-table-as-system-versioned-temporal-table/.
But, I am not able to turn on for UserRoles. I get an error
Setting SYSTEM_VERSIONING to ON failed because table has a FOREIGN KEY with cascading DELETE or UPDATE.
Does this mean we cannot know the versioning for many-many relationships?
For eg.
on 6/1 - User1 had role1 and role2, but
on 6/4 - User1's role changed to role1 and role3
So, if I wanted to know the state of the user on 6/1, I thought that's possible only by turning on system versioning on UserRoles, but that's not working.
Is this doable or not supported by SQL Server 2016? If not, is there any other way this can be accomplished?
It's important to notice that the limitation of using CASCADE on FOREIGN KEY constraints in temporal tables is applicable only to SQL Server 2016. In SQL Server 2017, this limitation doesn't exist anymore.
This is the relevant part from the official documentation:
ON DELETE CASCADE and ON UPDATE CASCADE are not permitted on the
current table. In other words, when temporal table is referencing
table in the foreign key relationship (corresponding to
parent_object_id in sys.foreign_keys) CASCADE options are not allowed.
To work around this limitation, use application logic or after
triggers to maintain consistency on delete in primary key table
(corresponding to referenced_object_id in sys.foreign_keys). If
primary key table is temporal and referencing table is non-temporal,
there's no such limitation.
> NOTE: This limitation applies to SQL Server 2016 only. CASCADE options
are supported in SQL Database and SQL Server 2017 starting from CTP
2.0.
Sounds like it's the ON UPDATE CASCADE or ON UPDATE DELETE foreign key that's the issue. Remove the cascading and replace that with a delete proc that knows and handles the proper relationships and you should be fine.
Personally, I like knowing what my deletes/updates are doing rather than trusting the relationships to handle all of them. I can see potential locking issues as well as know that there are times I really want to prevent an update or delete rather than letting it cascade through all of the tables unseen.
ON DELETE CASCADE and ON UPDATE CASCADE are not permitted on the current table. In other words, when temporal table is referencing table in the foreign key relationship (corresponding to parent_object_id in sys.foreign_keys) CASCADE options are not allowed. To work around this limitation, use application logic or after triggers to maintain consistency on delete in primary key table (corresponding to referenced_object_id in sys.foreign_keys). If primary key table is temporal and referencing table is non-temporal, there’s no such limitation.

How can I tell django to include "ON DELETE CASCADE" into the schema?

I use django (1.6) to create a postgreSQL database that I also access via other connections (currently java and C++). I have two tables that are linked with a foreign key and I want to use a cascading delete. Django simulates this behaviour by default in its own commands:
https://docs.djangoproject.com/en/1.6/ref/models/fields/#django.db.models.ForeignKey.on_delete
and I get the right behaviour if I delete the referenced object in the manage.py shell. (the referencing object is also deleted). But if I dump the sql-schema, I only find this Constraint:
ALTER TABLE ONLY object_positions
ADD CONSTRAINT object_positions_obj_id_fkey FOREIGN KEY (obj_id) REFERENCES
"Stored_objects"(id) DEFERRABLE INITIALLY DEFERRED ;
And I am not allowed to delete a row from "Stored_objects" if I have an object_position pointing to it via pgAdmin. I already use this in my models.py:
class object_position(models.Model):
class Meta:
db_table = 'object_positions'
obj_id = models.ForeignKey(Stored_objects,primary_key=True,db_column='obj_id',on_delete=models.CASCADE)
although Cascade is the default behaviour.
Is there a way to tell django to add "ON DELETE CASCADE" to the sql-commands?

JPA/Hibernate - updating database schema after changing PK of an entity

I need to change the primary key (#Id) of an entity from natural key to a new field that represents a surrogate key (it will use #GeneratedValue(strategy=GenerationType.AUTO)).
What is the easiest way to update the database schema other than dropping the table and letting Hibernate to create it again?
I was trying to let Hibernate update the schema automagically with hibernate.hbm2ddl.auto set to update, but it didn't work out. I suppose that Hibernate autoupdate doesn't support such drastic changes of database schemas.
If it were only one entity, I'd
make the changes in the database manually (SQL)
and update the Hibernate mapping accordingly

symfony doctrine build-sql error

I have some big problems with symfony and doctrine at the beginning of a new project. I have created database diagram with mysql workbench, inserted the sql into phpmyadmin and then I've tried symfony doctrine:build-schema to generate the YAML schema.
It generates a wrong schema (relations don't have on delete/on update) and after this I've tried symfony doctrine:build --sql and symfony doctrine:insert-sql
The insert-sql statement generates error (can't create table ... failing query alter table add constraint ....), so I've decided to take a look over the generated sql and I've found out some differences between the sql generated from mysql workbench (which works perfect, including relations) and the sql generated by doctrine.
I'll be short from now: I have to tables, EVENT and FORM and a 1 to n relation (each event may have multiple forms) so the correct constraint (generated with workbench) is
ALTER TABLE `form` ADD CONSTRAINT `fk_form_event1` FOREIGN KEY (`event_id`) REFERENCES `event` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
doctrine generated statement is:
ALTER TABLE event ADD CONSTRAINT event_id_form_event_id FOREIGN KEY (id) REFERENCES form(event_id);
It's totally reversed and I am sure here is the error. What should I do? It's also correct like this?
It it broken, I've wrote the schema manually and it works perfect. I didn't want to do that because it was a very large file, but I've also learned from it!
Thank you guys!
To get both visual representation and automatic code generation you can use ORM Designer so you will have everything covered by one tool.