NHibernate SchemaUpdate adding existing foreign keys again? - nhibernate

I'm using SchemaUpdate to synchronize my hbms with existing database. Database has recently created based on hbms and is completely up-to-date. But SchemaUpdate generates all foreign key constraints again.
For example suppose you have Student and Teacher. Student has association to Teacher with name ArtTeacher. ArtTeacher is a foreign key from Student to Teacher. Suppose database is up-to-date and currently holde Student, Teacher and their foreign key relation. So HBM and Database are equivalent. Know SchemaUpdate must not do anything but when I see its generated scripts, it re-produce that foreign key again.
Why this happens? Is there any way to avoid it?

The secret is to ensure that you specify names for the foreign keys, or else NHibernate will generate a random name which won't match the existing schema.
(I fished this answer out of the Google Cache of Afshar's blog post).

Related

Ruby on Rails Migration with Primary and Foreign Key

I am just starting ROR and making different tables for the SQLite database and am running into some trouble in relation to automatically generated id's of tables and foreign keys. To create my tables I used the "rails generate scaffold" command followed by the attributes that I needed. I went to the db/migrate directory and looked at what I had just defined. But I don't understand how I am supposed to explicitly reference foreign keys. I'm used to using Oracle so I'd normally do this process in the very first step during creation and be done with it already.
For example, I have a users table with some general attributes such as a username, password, etc. I also have an orders table with attributes transactionID (auto generated), userID (I want to this to be an FK), PartNo (FK key from the Products table). What I don't understand is how to use the auto generated key from the Users table and include it as a foreign key in the Orders table.
Also, I read somewhere else that if I put a line of code such as
t.integer user_id
in my create_orders.rb file then it would automatically know that this is a foreign key!?
I feel like this is probably really easy and I'm missing something. This is my first time using rails and I thought I got to define the foreign keys straight away via SQL. Any help would be greatly appreciated. If I could figure this out it would save me a lot of time.
After you do this, on your Order model, you'd use a belongs_to :user to generate the relationship and utilize the foreign key.
If you want to be able to go from User to Order, you'll likely be a one-to-many, so you'd have to do has_many :orders on User.
Here is the documentation for associations in Rails. And here is the specific documentation for belongs_to vs has_one.

Fluent Nhibernate mapping Legacy DB with composite key

I am using Fluent NHibernate (which I am fairly new to) in an application I am developing using a legacy Oracle DB. The DB has composite keys which are comprised of foreign keys and database generated columns. The generated columns are supplied by calling a DB function with the table name, and one of the other foreign key parts. The generated composite key parts are not unique, and I cannot change this. The generated key parts are often used as foreign keys on other tables too.
If I create entity mapping which specifies the composite key as it is in the database, then we cannot use any identity generation strategies, which breaks unit of work
If I create entity mapping which specifies only the generated column as the primary key, then I can use trigger-identity to generate the ids, and I get unit of work, but I then have a problem when I want to update, or access a child collection: The other parts of the key are not included in the WHERE statement.
Can anyone give me any advice on how to proceed?
If I stick with mapping composite keys, can I extend nhibernate to output the SQL to use trigger-identity? If so, can you suggest a starting point?
If I map a single column key, can I include other properties in a WHERE clause for HasMany mapping and Updates?
Unfortunately, as you have already found out, there is no support at all for this setup.
My suggestion is to do INSERTS manually (using custom SQL, for example). And yes, this breaks the UoW, but that is true of identity too.

Does doctrine 2.x must have a primary key in db table?

I'm setting up a project with Doctrine 2.1.5. I have got few tables without primary keys. I added some primary keys temporarily to generate Entities and Repositories.
But I will delete the fake primary key columns and remove the reference from Doctrine Entity as well.
Also I will be defining few columns as composite primary key in those table Entities (but not in tables).
Will there be any consequences (eg: wrong result from query or failing query) when joining those entity classes Because of 1. not having PK in database 2.adding fake composite primary key in entity classes?
Lots of tutorial and blogs mentions that needs to have primary key. But, never anything mentioned (which I can find) that the above solution is not a problem. (or it is a problem).
An answer from real experience would be great. But everyone welcome.
Thanks in advance for help.
P

Foreign key definition in sqlite

Is there any way to define relationship among tables and give foreign keys among them while using sqlite in Objective c
you can use foreign keys in sqlite the same way as in other sql-datebase systems but be aware that foreign key constraints in sqlite are not checked/enforced!
SQLite isn't a "real" relationnal-database, you can have fields that link to other tables primary key, but you have to control all from your code.
Same for deleting, no CASCADE or other integrity controls.
You can easily create a foreign key by adding a FOREIGN KEY statement to the SQL CREATE command.
For example when having a person and address entity:
Create the person table:
CREATE TABLE IF NOT EXISTS PERSON (ID INTEGER PRIMARY KEY AUTOINCREMENT, FIRSTNAME TEXT, LASTNAME TEXT)
Create the address table:
CREATE TABLE IF NOT EXISTS ADDRESS (ID INTEGER PRIMARY KEY AUTOINCREMENT, STREETNAME TEXT, STREETNUMBER INT, PERSONID INT, FOREIGN KEY(PERSONID) REFERENCES PERSON(ID))
This will mark the PERSONID column of the ADDRESS table as a foreign key pointing to the ID column of the PERSON table.
You can also find a full tutorial at:
http://www.apptite.be/tutorial_ios_sqlite.php
you can define foreign key relations in sqlite like in any other sql database system but to actually enforce them you need additional triggers. these can be compiled automatically from the database scheme with a tool shipped with the official sqlite distribution.
the big advantage of this solution is that it is programming language agnostic. once setup you don't have to care about the triggers in your source code anymore. see http://www.sqlite.org/omitted.html for more information.
If you use the Cocoa CoreData framework, and define a managed object model, using SQLite as the persistent store - you can specify the relations between your model, and specify deletion rules ( such as cascade or deny ) and these will be performed and validated as you make changes to your entities from Objective-C, and committed back to the database when you save.
The relationships and rules are very similar to database foreign key rules, but are performed by the CoreData framework inside the objective-C runtime. The SQLite database is just used as a persistence store for your managed object graph.
Here is the CoreData programming guide at the Apple Developer Site:
NB This framework is Cocoa-specific, and your question doesn't explicitly mention using Cocoa, just Objective-C
You can set one flag in SQLite for foreign key relationship.
Step 1: Go to tool menu in SQLiteManager.
Step 2: Open On-Connect SQL tab.
Step 3: Set "PRAGMA foreign_keys=ON;" and save it.
You can use database as normal PK and FK relationship.
Thanks.

NHibernate throwing SQL CE Error 25026

I am using NHibernate with a SQL CE desktop database, and I'm getting an odd error when I try to do an update. SQL CE is throwing Error 25026: "A foreign key value cannot be inserted because a corresponding primary key value does not exist."
The exception occurs when performing a cascading update of a collection property of an entity object. The entity object is an Owner, and the collection property is Projects (IList), the projects for a particular Owner. In my database, the primary key of the Owners table is a three-character string (the owner's initials), with a corresponding foreign key in the Projects table.
Here's why I am puzzled: NHibernate can fetch all of the records for a particular owner (for example, "DCV"). And in my code, I can add a new Project object to Owner.Projects with no problem. I take the owner ID value directly from the Owner object fetched from the database, so I know the primary key exists in the Owners table. But when I do an ISession.SaveOrUpdate() on my Owner object, I get the foreign key error described above.
Am I dealing with some idiosyncracy of NHibernate, or some mundane error in my code or mappings? Any thoughts that would help me troubleshoot this problem greatly appreciated!
David Veeneman
Foresight Systems
I found the answer. It has to do with how NHibernate handles one-to-many associations. From the NHibernate Documentation, Sec. 6.4, One-To-Many Associations:
Very Important Note: If the
column of a association
is declared NOT NULL, NHibernate may
cause constraint violations when it
creates or updates the association. To
prevent this problem, you must use a
bidirectional association with the
many valued end (the set or bag)
marked as inverse="true". See the
discussion of bidirectional
associations later in this chapter.
If you are having this problem, remove the foreign key constraint temporarily and run your code, outputting NHibernate's SQL to the console. You will see that NHibernate first inserts the new record without the foreign key, then calls up the record, then inserts the foreign key into the record. The first operation is what generates the foreign key error.
The solution, as the NHibernate documentation points out, is to make the relation bidirectional.