As I understand it NHibernate has a build in support for timestamps. However, it appears you can only instruct NHibernate to never update the property or always update it.
In the project I am currently working on there are several tables which have both "created_time" and "updated_time", both are to be generated by the database.
I can't figure out how to instruct NHibernate to use "getdate()" for both properties nut only on insert for "created_time" and on insert and update for "updated_time".
Is this possible?
PS: I am working with a legacy database and I am not allowed to change it, so triggers etc. are not possible solutions.
You could work around this by creating an Interceptor that sets those values, but offcourse, then those values are not generated by the DBMS offcourse ...
It might be a workaround, as I also don't know how to make sure that the DB populates those values, but I'm also interested in another solution for this issue. :)
Which version of NHibernate are you using?
In 2.0, the "generated" tag on a property has three valid values:
never (self-explanatory)
insert(will retrieve the generated value only on inserts)
always (always retrieves generated value).
Related
I have just added a IsValidRecord column to a MyClass SQL table.
It will be used as a logical delete / soft delete.
Now I need to update my application to only query the valid records based on the new column.
I use Entity Frameword DB first.
Our app uses a business layer that centralizes all methods fetching the MyClass items.
So I have updated all the methods that query the concerned table with the appropriate filter based on IsValid.
It works fine.
However, I am pretty sure that these are bad practises because devs will forget to set this filter on new methods that will be added in the future, which will obviously bring incorrect records.
I wonder if EF would have features to automatically filter the queries with the appropriate "AND IsValid = 1" filter?
I used to be working for a company doing the same with NHibernate.
The only supported feature that I have seen for EF is this:
Soft Delete
Unfortunately,it overwrites OnModelCreating so I take it that it only works for Code First architecture.
We use DataBase first so I think it does not work as OnModelCreating is never called?
I would normally implement this filter using application-specific views in the database (after all, some uses of this data may need to be able to see deleted items).
With a simple definition for the view, they should automatically be considered updatable by SQL so you shouldn't need to have to write triggers to manage INSERT/UPDATE/DELETE operations. You then lie to Entity Framework about what its "tables" are and it should mostly be none-the-wiser.
Depending on how you want the soft-delete to work, you may choose to hide the existence of the IsValidRow column (nit: we have rows in SQL, not records) in this view and implement an INSTEAD OF DELETE trigger on the view allowing your application to soft delete these rows by asking EF to remove them.
The best link I have found is this:
EDMX Mapping
Use EDMX designer to add the filter condition. It's basically exacly what I want...
Are there any down sides for this solution?
At first sight, it sounds good enough to me.
Only disadvantage that I can think of is that the filter is well hidden. Other devs in the future might have very hard time to figure out why / where / how are the entities filtered.
We have a very old application with multiple databases. Recently we decided to make a switch from MSSQL to PostgreSQL. During the process we decided to keep all the table and column names in lower case. This affects our code a lot. We want to go with minimal change approach.
Problems :
Table name changes - We thought of overriding getters and setters for the table_name in model to avoid changes at many places. Creating a module and then including that in all the models was one option. But our setter can't get control because of "ar-octopus" gem. It actually hijacks the setter for table_name. So this approach fails.
We tried mapping dynamic methods like "find_by_UserID" to "find_by_userid" by overriding "method_missing". But dynamic_matchers in activerecord has marked the method as private, so this also doesn't works.
The only option now seems to be refactor the whole code to suit the table and column name changes. But we have used queries, direct column accessing like #person["Name"] in views as well and use of many dynamic functions like mentioned in point 2. So even after refactoring the whole code and testing it completely we wouldn't be sure whether all the code has been updated properly or not.
We want refactoring to be last option. But, don't know any other better way.
I'm using Nhibernate and Fluent Nhibernate.
I fell into the trap I think a lot of new users fall for, and ended up with all my varchar columns at 255 chars. For politic reasons far too boring to go into, there was immediately data in these fields that I'm not supposed too delete (boo) so I need to update the column lengths without dropping and re-creating tables.
However if I apply a convention for string length to the Fluent configuration, and use the NHibernate UpdateSchema method, only new tables seem to get the new varchar length. Is this correct and is there a way to apply this to the existing tables??
you don't necessarily need nHibernate for that..
you didn't mention what the underlying DB instance is, but I'm sure it has options for updating column properties. I think it's the simplest solution.
UpdateSchema only applies non-destructive updates. It is not meant as a migration utility, but for rapid changes to models/database tables during development. For more information, see my answer to NHibernate, ORM : how is refactoring handled? existing data?.
One thing that bothers me about nHibernate is that it is not 100% compile time tested.
If I rename a column in my database table, and I update the mapping file for that table, when I hit compile I should get errors in all my query code (hql/criteria whatever) of where I referenced that column name and how it is spelled wrong.
The whole point (for me anyway) of using an ORM was that database changes won't break my queries.
In other words, I will be notified at compile time of what needs to be fixed, instead of getting runtime errors etc.
To achieve what you want I think your best solution is to use a combination of Fluent NHibernate and nhlambdaextensions. Fluent NHibernate will give you type-safe checking on your mapping files (so if you change a property on your entity, the compiler will throw an error if you don't also change the property on your mapping class). The lambda function extensions will give you type-safe queries via the Criteria API (not HQL since that's just magic-strings SQL-with-objects).
Also to clarify your question, you said:
If I change a column (rename) in my
database table, and I update the
mapping file for that table, when I
hit compile I should get errors in all
my query code (hql/criteria whatever)
of where I referenced that column name
and how it is spelled wrong.
Just changing the database side should break nothing (assuming you also make the change in your XML mapping file). Your code does not reference the column="first_name" portion of the mapping, it references the name="FirstName" portion. If you do not change your entity, renaming a column (from "firstname" to "first_name", for example) in the database will not break your queries as long as you update your mapping file as well.
You should look at Castle ActiveRecord. I used this before and it allows you to not worry about the mapping files (.hml) as much. It lets you make your changes at the class level definitions, and the mappings files were generally untouched.
If you are writing bad queries, that sounds like a design problem, not an nHibernate problem.
You won't get errors providing the Property names haven't changed, as most people use HQL for their queries in NHibernate.However if you do change the Property names and not the HQL you will indeed get broken queries, e.g.:
FROM User Where User.Surname = 'bob'
Change the Surname property to Lastname and it'll break. It's a feature lacking in NHibernate but would make a good project for the contrib - a Subsonic style query interface. This a project sort of similar but still use HQL.
As mentioned above ActiveRecord and Fluent NHibernate are the closest to type checking with NHibernate. Both enforce that you inherit your classes from their base class, as you'd expect and ActiveRecord is not intended for production use - Ayende has said in a video that's meant to be a prototyping tool for NHibernate.
Hibernate uses dynamic byte code generation to create the mapping classes, based on the mapping configurations.
The fundamental point of ORM is to enable auto-magical mapping (bridge) between Objects and Relational systems. Thus: ORM.
if you want to strongly type your objects rather than using xml config which can cause alot of runtime issues if not properly tested, I would look into FluentNHibernate which has convention maps that allow you to map your classes to data in code. Made my life alot easier especially when first starting with NHibernate wish i had found it before i knew how to properly map using xml
Does NHibernate have the equivalent of the Java version's schema validator? In which case, you could add a step to your build process to build the session factory and run the validator-- building the session factory should also compile named queries, hence validating them too.
Hmm, looks like it supports something like that: http://nhibernate.info/blog/2008/11/22/nhibernate-schemavalidator.html
NB this means your build process will fail to work if your dev database is not available--- which I would regard as a bad thing.
General Info:
ASP.NET MVC app
using ADO.NET Entity Framework
SQL Server 2005
I have a few tables that more or less have a hierarchical structure of mostly one-to-many relationships. Most if not all of them have a Last Modified column and my question is simply how best to go about making sure that this column is updated properly throughout the hierarchy. I would prefer to have it done at the database level automatically, I'm just not sure how. A colleague mentioned triggers while at the same time mentioning that they might not be the best way to go. I don't know whether to do this within the class I'm using to manage the model or at the database level. I'd prefer not to have to keep updating each reference individually as that gets tedious and I'd have to make a bunch of separate functions for each level.
My questions then are:
Is there some way to do this at the database level with a stored procedure I could call?
If not, what would you suggest I do on the application side of things to best handle this programmatically?
If any more info would be helpful, I'll be happy to provide it, I had a difficult time trying to figure out how to even ask this question.
Another person had the same/similar question here. Their opinion use a trigger. Here's the full response:
Sql Server (Entity Framework): created_at , updated_at Columns
It depends on where you want your penalty to be. You can have it one of two ways.
Use a trigger to propagate changes up your hierarchy. This might be best when you write once and read a lot. eg: Update an address and the last modified gets set on the parent records as well as the address itself.
Just update one last modified and then query for everything when you need to see when something has been modified. This might be best if you write a lot, but read very little. eg: Only update the last modified on an address. When you query for changed records, query for records that have a last modified or records with addresses that have a last modified.
It's hard to say without knowing your situation. If you need to update all related last modified dates, then I would go the trigger route just to keep things simple.