by Mikael Henriksson
19. September 2009 14:47
I just wanted to tip everyone about a great website I found http://codepaste.net/ . There are a couple of things I like to mention about it. First of all it’s a great place to get some formatted code for mailing groups. I’ll start using it vigorously for that purpose. There is “Copy As Html” add-on for visual studio 2008 but it does not make sense after joining the dark side! Second the URI to access the snippet is short enough to be used for twitter! Third it’s a great way of finding other snippets! :)
c8863cfb-803b-496d-8472-a6d4a3c3ef1d|0|.0
Tags: Tools
Tools
by Mikael Henriksson
19. September 2009 13:37
I find myself drifting more and more towards something I believe is TDD. When I start with something new I go to my test project, write a test (spec) of what I want to accomplish and then try to produce code that tries to satisfy the spec (test).
I don’t care that much about what others say about patterns or whatever I just care about that things should work. It’s not like I can blame anyone except myself if I cause a stop in production. There for I like to follow some steps when I do testing.
- Simple unit tests
- Data verification tests
- Integration tests simulating a client
- Using a real client
If I get success on all these I don’t mind saying ooops if something goes wrong. Without knowing that my functions do what they are supposed to, that the data sanity is in check and that both simulation and real clients work as they should I don’t like to release things. Fortunately this is not very hard to achieve and even badly written, hard to use tests are much better than not testing at all and practice makes perfect :)
by Mikael Henriksson
19. September 2009 13:12
NHibernate performance sucked yesterday. Not because NHibernate itself is slow but because I wasn’t using it correctly. In a (by yours truly) newly created system I was not only using NHibernate for minimal performance. I was also using it in an unsafe manner. In case something went to hell there was no easy way for me to roll back the changes. This is particularly bad in a system for let’s say billing. Let’s say we grade/rate/prepare 80,000 customers for being billed. I don’t want this process to complete if there is something wrong with even a single record I want it to hit everyone in the face that –“Hey guys we have no customers to bill, wtf should be done about it?”. At the same time rating 1000 records was taking around 5 minutes.
After some tweaking here and there without much of a difference I decided maybe it’s time to try something crazy like using a unit of work for the entire process. The logical unit of work with minimal effort is of course the transaction. Easy enough I place all the existing code in a transaction, check if a transaction is open in the dao/repository/data context and then only issue a SaveOrUpdate(entity) if this is true. At the end of the processing of all the message I issue a transaction.Commit() and I have set the FlushMode to FlushMode.Commit. I went from 1000 records in 5 minutes to 20,000 records in 30 seconds. After the first 20,000 inserts/saves/updates depending on what the rating does it becomes slower. This does not surprise me a bit since I am not releasing any resources and that has nothing to do with NHibernate. That has to do with bad resource allocation and bad crap management on my end.
This is the short version of what the main code would look like:
using (session.BeginTransaction())
{
try
{
session.FlushMode = FlushMode.Commit;
IEnumerable<Record> records = GetAllRecords(); // load tons of records
foreach (var record in records)
{
// do loads of operations
_recordRepositoryDataContextDAO.SaveOrUpdate(record);
}
session.Transaction.Commit();
}
catch
{
session.Transaction.RollBack();
throw;
}
}
And the method to persist the changes:
if (_session.Transaction == null)
{
using (var transaction = _session.BeginTransaction())
{
_session.SaveOrUpdate(billingRecord);
transaction.Commit();
}
}
else
{
_session.SaveOrUpdate(billingRecord);
}
by Mikael Henriksson
14. September 2009 02:12
While waiting for my NServiceBus article to finish I have yet another quick post on the Fluent NHibernate and particularly the mapping. I see people do mapping conventions and mapping overrides and struggling with getting the results they want. Part of me want to laugh in their faces for being silly. For me it’s not an option because as Andreas Öhlund said : “is the local dba police on your back” Yup he is so I can’t really have anything auto generated. I simply doubt that many of us have that luxury even. What I did learn however was to sort of connect the two and besides it feels quite nice knowing my mappings will just work. I shortened my mappings a bit with inheritance.
public class PersistentEntityMap<T> :
ClassMap<T> where T : PersistentEntity
{
public PersistentEntityMap()
{
Id(x => x.Id)
.Column(typeof (T).Name.ToLower() + "_id")
.GeneratedBy.Identity();
Map(x => x.CreatedAt)
.Column("created_at")
.Not.Nullable();
Map(x => x.CreatedBy)
.Column("created_BY")
.Not.Nullable();
Map(x => x.LastChangedAt)
.Column("changed_at")
.Nullable();
Map(x => x.LastChangedBy)
.Column("changed_by")
.Nullable();
}
}
In this totally uninteresting project I am working on for myself because I like it I just saved myself from having to repeat myself unless of course someone needs something else. This could be improved further though. I am not completely happy with this solution. Something is missing. I don’t need change tracking for all my persistent entities. Darn it I would really love multiple class inheritance for this but I guess I’ll have to make due with the following:
First a persistent map
public abstract class PersistentEntityMap<T> :
ClassMap<T> where T : PersistentEntity
{
public PersistentEntityMap()
{
Id(x => x.Id)
.Column(typeof(T).Name.ToLower() + "_id")
.GeneratedBy.Identity();
Map(x => x.CreatedAt)
.Column("created_at")
.Not.Nullable();
Map(x => x.CreatedBy)
.Column("created_by")
.Not.Nullable();
}
}
And then a map with change tracking that inherits for the main map that my classes that make use of change tracking could benefit from:
public abstract class PersistantChangeTrackingMap<T> :
PersistentEntityMap<T> where T : PersistentEntity
{
public PersistantChangeTrackingMap()
{
Map(x => x.LastChangedAt)
.Column("changed_at")
.Nullable();
Map(x => x.LastChangedBy)
.Column("changed_by")
.Nullable();
}
}
This might come as a shock for someone but I am used
by Mikael Henriksson
1. September 2009 02:33
When your browser gives you http 500 error while trying to connect to a web service it’s usually because you forgot to add a little something in the web config.
<configuration>
<system.web>
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
</system.web>
</configuration>
Since I was really really tired it took me 20 minutes something figuring out because I did not get this very nice error message at first!! Grrrr