I have a separate script that creates the database and tables for each database that we are supporting. I am using JPA to manipulate the data in the database, but JPA does not create the database or the tables.
I want to add a foreign key to a new table with a cascade property so that when a row is deleted in the parent table, the corresponding rows in the child table are also deleted.
I am aware of the annotations necessary to do this in JPA, however I can create the foreign keys and the cascade statements in the script I am using to create the databases.
My question is, since I am using a separate script to create the database tables, can I just add the foreign key / cascade statements in the script and then ignore all of the JPA relationship annotations? Is there advantages/disadvantages to adding this information in both the database script as well as in the JPA code?
You should always have a 2 level check. if you do not use the features of JPA, then it's a big waste of the functionality JPA provides. you should actually make sure that you JPA relations match your DB relations as closely as possible. It will help you a lot as JPA can cache data and even prevent unnecessary calls to DB.
eg if u have a not null constraint and you persist with no JPA constraint, your DB has to do all the work and throw the exception back.
normally in an application, the network and DB are the slowest factors in the app. so you should try mimicking the constraints in JPA to avoid unnecessary overhead.
also using such constraints you can form bidirectional relationships and have collections of associated entities and many more such advantages.
Related
I am working on a project manually mapping entities from a SQL db. My primary source of information about columns, keys, relationships, and others is the rlinq generate by Telerik from the db.
I wonder if it's possible to detect a many-to-many relationship based on only in this file.
I have two databases that I have connected using linked servers.I have DB1 and DB2 which I only have read access to. I'm using DB1 for my application and have linked DB2 so I can combine queries. Is it possible to have foreign keys in DB1 that are linked to DB2?
No, it is not possible to create foreign keys between objects in different databases (even if they are on the same server). The official documentation is pretty clear about that:
FOREIGN KEY constraints can reference only tables within the same database on the same server. Cross-database referential integrity must be implemented through triggers. For more information, see CREATE TRIGGER (Transact-SQL).
It even points you to the possible workaround, i.e. to try to implement some kind of referential integrity checks using triggers. You can add after insert/update triggers on both sides to validate the data changes, and after delete triggers on the primary table to check are there child records. If the validation fails, you will raise an error. You can also use instead of triggers.
But the solution with triggers will not guarantee the referential integrity anyway. You can lose connectivity between databases. You can restore one of the databases from older backup. All kind of things can go wrong. You better try to reconsider your database design. Is it possible to combine these two databases into one? Is it possible to maintain copies of both tables into each of the databases and try to replicate stuff?
I found this solution for a problem I have: how to generate entities with JPA annotations from a given database.
IntelliJ IDEA 10 generate entity (POJO) from DB model
Now with IntelliJ I'm given the possibility to create relationships between entities manually. Is there a way to generate them automatically as it did with entities?
I used the REFERENCES keyword when needed while creating the database. I suppose there should be an automatic mapping of relationships as well!
When Generating entities from DB Schema in dialog there is an option to 'Show default relationships' which when selected will display FK relationships when selecting tables to generate entities from:
I have been working on a very data intensive application that has around 250 tables. Recently there have been some design changes required. Some of the design changes require adding new tables and linking those up with existing tables (foregin key) in a 1-N manner for parent - child relationships (in ORM).
Take this example. Current design allows for one Rental Vehicle per Contract. New design requires multiple Vehicles in the same Contract with Multiple rates.
So the data in one table needs to be put in 2 additional tables now.
I have completed the changes to the schema but I can't deploy those changes to the test environment until I find a way to convert the existing data and put it in the new design format.
My current process.
Add 3 new Tables nContract, nContractedAsset, nContractRate
Copy information from Contract table into 3 new tables. Preserve primary key field on nContract table same as Contract table.
Copy foregin key references / Indexes / Rights to nContract from Contract table
Drop Contract table
Rename nContract to Contract and so on.
The only issue I have is I am not comfortable doing part 2 in SQL. I want to use the power of the ORM and .Net to do more intelligent and complex tasks for more complex scenarios than this example
Is there a way I can write the data migration using ADO.Net or ORM for step 2?
What are best practices or the processes for this? Am I doing something wrong?
I ended up using FluentMigrator https://github.com/schambers/fluentmigrator
It allowed me to do Entity Framework like migrations (See: Ruby On Rails Active Records migrations)
Most of the DDL can be written in .NET in a fluent format. It supports UP and DOWN migrations wrapped up in transactions and even supports full SQL scripts for data migration.
Best thing about it is all your migration scripts can be put in source control and even tested.
I'm building a new NHibernate 3.3 application that must connect to a legacy system in order to look up some information about my users. There's a separate, read-only, database that holds course enrollments that I'd like to use to populate a collection on my Student entity. These would be components in NHibernate-speak, consisting of a department code and course and section numbers, like "MTH101 sec. 2"
The external database has a surrogate key, the student number, which corresponds to a property in my User entity, but it's not the primary key of a Student.
These databases are on separate servers. I can't change the legacy database,
Do I have a hope of mapping the enrollments collection as NHibernate components?
Two Options
When you have multiple databases or multiple database servers that you're trying to link together in a single domain model using NHibernate, you basically have two options.
Leverage the database server's capabilities (linked servers, etc.) to join the data so that NHibernate only has to worry about connecting to one database. In your NHibernate mappings, you fully specify the table attribute so that the database server knows to query against the other database server. For your "surrogate key, ... not the primary key", you could map this using <many-to-one property-ref="...">.
Use multiple NHibernate session factories, one for each database. You would be responsible for coordinating what gets loaded from which database. You configure each session factory for just the tables that exist in that database and with the appropriate connection string. Then, to load the data, you execute two queries, one against one database, and another against the other database.
Which one?
Which is the right choice? It depends...
Available features
If your database server doesn't have any features to support #1, or if there are other things preventing you from using those features, then you obviously have to use #2.
Cross-DB where Clauses
#1 gives you more flexibility when writing queries - you could specify where clauses that span both databases if you needed to, though you need to be careful that the query you write doesn't require database A to fetch tons of data from database B. With method #2 you execute a second query to get what you need from database B, which forces you to be more conscious about exactly what data you have to fetch from each database to get the job done.
Unenforced relationship
There won't be any foreign keys enforcing the relationship because the data lives in two different databases. NHibernate (very reasonably) assumes that database relationships are enforced by foreign keys. Since there's a chance these two databases could be out of sync, #1 will require you to resort to things like not-found="ignore", which has performance implications.
Complexity of Deployment
Inter-database relationships make deploying to various environments (DEV, QA, PROD) difficult. You can't just deploy the application and database, and make sure the application's connection strings are pointing at the correct databases; instead you also have to make sure that any references inside the databases to other databases are pointing to the correct places.
Given all of the above factors, I usually lean towards option #2, but there are some situations where #1 is just so much more convenient.