Thursday, February 28, 2008
Dumb errors with NHibernate
After about 30mins of seraching I noticed I had clipped the name too much and had removed the .hmb. part out of the file name in the mapping file... well thats annoying!
Monday, February 25, 2008
Ayende's "Unity" review
My 2 big issue are the seperation of concerns and error handling.
Just by looking at code that use ObjBuilder (i.e SCSF etc) you know it is using OjbBuilder due to all of the ugly dependecy attributes everywhere, i was really hoping this was not going to be carried into Unity.
As for not throwing an exception on not finding an implementation i find the truely odd default behaviour.
http://ayende.com/Blog/archive/2008/02/24/Reviewing-Unity.aspx
Thursday, February 7, 2008
NHibernate many to many collections
Upon investingation it appeared it was the collections of some of these entiies that were causing the issues, not the enties themselves. I finally realised that we where creating entities for the join tables in the DB (which to me didnt really make sense), thus cause self referencing relationships in the object model, not a good place to be if this needs to be serialised to XML!
A bit of a clean up to the mapping files and we look to be all good.
I am sure this is the most trivial of trival ORM mapping stuff, but it was something that went un noticed around here for months, or at least swept under the rug by those that did.
Below is a the email outlining the scenario....
EMAIL TO WORK TEAM MATES
*If you use Nhibernate or other ORM’s this is of Note, otherwise feel free to delete*
Background (trivial, but work with me here)
- We have a whole bunch of Data Entities/ Database Tables that have “one to many” or “many to many” relationships
- We use joining tables to create these relation ships I.e. to join AssetMetadata & GenreType we use AssetMetadataGenreType table.
- We use an ORM (NHibernate) to convert the table structure to a usable C# managed code structure.
- We also use the ORM to map these relationships.
- Unfortunately we are mapping these tables too explicitly. There really is no such entity as an AssetMetadataGenreType, only an AssetMetadata entity and a GenreType entity. The AssetMetadataGenreType is only a relationship that has no context on its own.
This over eager mapping of joining table may be the problem of our serialisation issues.
Fore example: Currently we have a AssetMetadata entity that then has a collection of AssetMetadataGenreType with each one relating to a AssetMetadata and GenreType entity. The problem here is that every one of these causes a self referencing scenario (AssetMetadata è AssetMetadataGenreType è AssetMetadata). Normally no one would care. Serialisation however does not like this, as self referencing data and XML do not play nice.
Solution: Don’t map the joining tables.
These are not real entities so should not exist in the managed code world. They only exist in the DB thru necessity.
Step one: remove all of these mapping entities (well maybe not delete, but start re-factoring where possible)
Change the mapping so the subject entity knows about its relations. Inverse this relationship in the other mapping files IF NESSECARY. i.e. genre types do not need to know about there related asset metadata
Example below:
<!-- The links to associated genres --><!--
<bag name="AssetMetadataGenreTypes" lazy="true" inverse="true" cascade="all-delete-orphan">
<key column="ASSET_METADATA_ID" />
<one-to-many class="AssetMetadataGenreType" />
</bag>-->
<!-- RC: 07/02/2008: Trying a different approach so we dont try to pass self referencing data around,
I think this is a dormant issue waiting for collections to populate before it rears up and attacks us-->
<idbag name="GenreTypes" table="ASSET_METADATA_GENRE_TYPE" lazy="false">
<collection-id column="ID" type="Int32">
<generator class="sequence">
<param name="sequence">ASSET_METADATA_GENRE_TYPE_SEQ</param>
</generator>
</collection-id>
<key column="ASSET_METADATA_ID"/>
<many-to-many column="GENRE_TYPE_ID" class="GenreType" fetch="join"/>
</idbag>
Another benefit includes faster update times as we are taking advantage of the index of the primary key on the join table.
http://www.hibernate.org/hib_docs/nhibernate/html/collections.html#collections-idbag
I still have to test the hell out of this, however prelim test are all positive.
Rhys
Tuesday, December 25, 2007
Post sharp
You can assign what you want to it as it is just an object and is bound to the eventArgs of the enter and exit events.
Sweet.
This means you could also make every single method a transaction if you wanted to (if you were Juval Lowy/mad man), or mark entry and exit of a specific instance call of a method using a GUID as colleague had mentioned would be nice for logging.
As this is weaved in to the IL its should have not have any more a negative performance impact on calling the method, over over putting the code in to the method to do exactly the same. You do however have a whole load more flexibility to pull out and put in what you want and where (ie certain assemblies, classes or methods).
I am loving PostSharp :)
Monday, December 24, 2007
DBC within the C# language - Spec#
I have been hoping for something like this for quite awhile. I am hoping this will be something that will aid in compile time assistance for Design By Contract programming.
I have been looking into third party apps and even building my own libraries, however what i really wanted was compile time errors as opposed to run time errors, which although Test would usually find, don't really help other developers as they leverage of my code.
Currently i have comments and run time checks however this still does not force consumers of my method to adhere to the contract, it only throw run time exceptions when they break the contract. the benefit here is they fail fats and they get a more meaningful exception message as to WHY the parameters are not valid. But it often also means that i have code the looks like:
public class Foo: IFoo
{
public void Bar(object param1)
{
Check.IsNotnull(param1, "Foo.Bar: param1 can not be null");
if(param1 != null) //***this line is effectively redundant
{
//do something with param1...
}
}
}
The null check is still in place to prevent FXCop errors arising by not checking for the objects state before using it.
I really hope the Spec# C# additions will aid in this.
Tuesday, December 18, 2007
When is a bug not a bug?
He is in a position where he knows what the application we are building should do and how it should do it. Unfortunately this is only ever communicated to me after I have built the module. He doesnt write the use case so dosen't get a chance to prewarn me.
These changes are raised as bugs (as we only have the concept of bug, no concept of a change request) and so it looks like my code sucks as i have a couple of dozen bugs logged against my name (which is standard across the team). I dont like the idea of my code sucking. While looking through the buglist today, after reading the first 12 and realising that they were either A) Not bugs, but changes or B) not my bugs to fix; I got a little stroppy.
*begin blowing trumpet*
Now, when I get a use case I assume that this is what is required... I know, what an idiot... so I write my unit tests and do the whole Red, Green, Refactor like a good TDD agile boy,
*end blowing trumpet*
however I forget that we only call ourselves agile we are in fact... dreamers.
Huge numbers of tests fail and are left unattended, iteration after iteration... our scope is non existent.. our use case are guesses at what we kinda, maybe want and are completely ok to change at any time with the expectation to deliver on time still intact.
So I have tried to push back.
-A bug is raised
> If in use case ==> FIX NOW!
>Else ==>can be done in next iteration and is logged as "Not in spec/Functional change".
I thought this may rustle some feathers and hopefully means the uses case would be a little more robust. It also means the actual bugs got higher priority, as I think they should.
No...
Now we just do non-functional iterations where we do "bug fixes" on all the functionality that was never originally asked for.
As there are a few developers (6-12) all on UK rates (not exactly cheap) and one BA (still only UK rates, but only 1), I would think it would make sense to focus the effort on the up front work, hell maybe even hire another "BA" so the development team don’t have to handle code 2,3,4 + times.
It also means the teste (again on UK rates) has to test and then retest every time the change is made... how do you spell D.R.Y???
To say this annoys me is somewhat of an understatement. It is pretty hard to be focused and passionate about what you are doing, knowing full well in only a few hours/days/weeks it will all get thrown out because someone threw together a Use case, with out putting more than 5 minutes thought into it.
More time scoping => less time "bug fixing"*
*i.e. retrofitting missing functionality
Now I know Agile encompasses the ability to "handle change", but never getting the original scope correct... ever, through laziness, is not Agile, it's just software cowboy bollocks.
Unfortunately nothing is going to change. This could be a really good project, even a flag ship project for the company as it is using new exciting tools for the comapny (.Net 3.0, Nhibernate etc) and it would honestly only require the smallest extra bit of effort. But it wont and that’s a shame.
end of yet another rant...
M$ and OSS playing nice!
Windsor, Spring.Net and StrutureMap can now bolt in directly in to the new MVC framework... hopefully this is a begining... :)
