3

I'm trying to refactor (actually, rewrite) an application which currently uses only stored procedures to access the database (hundreds of SPs). My goal is to use Nhibernate and follow a good design as much as possible. But since the database (and the SPs) are used by dozens of other apps, I can't really change the db design. And off course, it's awful.

I'm facing a design problem and I can't really find a good solution. I have a table called movies which contains movies, but these movies can be different "things". For example, this table contains movies as well as episodes of tv shows and the only way to know the difference is a field named "episode" which is set to 0 for movies and 1 for episodes.

My objective is to expose the following class hierarchy :

public abstract class Program {}
public class Episode : Program {}
public class Movie : Program {}

Currently, I have mapped the whole movies table to a model class MoviesModel and then I build my Episode/Movie class through AutoMapper and a factory method in the Program class :

public static Program Load(MoviesModel movieModel)
    {
        if (movieModel.Episode > 0)
            return Mapper.Map<Episode>(movieModel);
        return Mapper.Map<Movie>(movieModel);
    }

This seems really wrong on many levels : I have an anemic data model since my MoviesModel is totally empty of any business logic, the automapper stuff becomes really hard to maintain when I add many other entities with relations to Movies, and I break the lazy loading with AutoMapper.

I heard about the any mapping of nhibernate but it doesn't really solve my issue, it just creates sub components of a class.

So my questions are :

  • Ideally, where should be my business logic ? I guess in the MoviesModel class but I don't really like the idea to expose my database fields.
  • Is there a way with nhibernate to map the same table in different classes based on a field value ?
  • Is there a point to wrap the nhibernate objects if I want to provide a "clean" public API ?

My goal is to build a base library which will be used (hopefully) on other legacy apps so I want to provide a clean API with logical methods and without exposing the database mess even if I still have to deal with it.

Thanks for any help to put me in the right direction.

2
  • Do the other apps "only" use SP's or do they have code accessing tables directly? You could change the database schema and make sure the SP's return the same data. The other apps shouldn't know the difference.
    – JeffO
    Jul 18, 2013 at 13:24
  • 1
    I really don't think using complex domain model with legacy database is going to work. Mapping complex object design to relational model is complex even when you create the DB. Doing it with existing database is crazy.
    – Euphoric
    Jul 19, 2013 at 19:36

2 Answers 2

1

Unfortunately I don't know much about AutoMapper but I can offer a solution to your second question. Fluent NHibernate is a tool to aide with your NHibernate mappings, allowing you to configure them in a programmatic way rather using than XML. One of the methods you can call when setting up your mappings is DiscriminateSubClassesOnColumn() which allows you to specify the database column that will be used to create your sub-classes. Then in your sub-classes you specify the DiscriminatorValue which can be an enum.

Here is what I imagine your mappings to look like (untested code):

public class ProgramMap : ClassMap<Program>
{
    public ProgramMap()
    {
        //map your fields as normal, eg: Map(p => p.Id), Map(p => p.Name)
        DiscriminateSubClassesOnColumn<int>("Episode");
    }
}

public class MovieeMap : SubclassMap<Movie>
{
    public MovieMap()
    {
        DiscriminatorValue(0);
    }
}

The problem may actually be specifying the DiscriminatorValue for your Movies but hopefully this gives you something to go on. For reference I've used the following links to put this answer together so they may be worth a look in case I've missed something out.

Note that if you don't specify the DiscriminatorValue, Fluent NHibernate assumes that the discriminator column contains your class name (which would be a terrible database design!).

2
  • This is fascinating. I never knew this about Fluent NH (and it is our primary orm where I work). I will be sharing this! +1 Aug 24, 2013 at 16:34
  • FluentNH does nothing more than just making hbm files behind the scene. NHibernate supports inheritance and it does it in several different ways. And of course it can be configured by FluentNH (which is now dead), NH Mapping-By-Code (this is really what you should be using instead of Fluent) and by classic hbm files. Oct 10, 2013 at 21:18
-1

@Dawmz, I am not big fan of ORM frameworks. Note that I am developer of Valentina Database, so know how things work internally in dbs.

In your case you already have hundreds SPs used by dozens(!) of other apps.

This is the best scenario for SPs, because you have central place where logic present ONCE. If you remove some SP, then where will go logic of that SP? Into dozens places? On different languages probably? Road to the hell.

As I understand these SPs was developed by somebody before you come? He/They did very good job. Do not break things.

3
  • Yes OP. Go tell your boss that you refuse to re-write this application because "someone else did a good job".... This doesn't answer the question. There are plenty of reasons why a business would want to move business logic out of a database. In fact, where I work right now it is an accepted general rule that databases work on data.. and code performs the business logic. Aug 24, 2013 at 16:32
  • @Simon, :-) probably your boss then should become CEO of Oracle and/or MS SQL, and yet dozen of big DB companies to fire on the next day all groups that develop Stored Procedures in DBs. Really who need that if your boss think so. My answer DO answer and resolve root of problem on original question. No need to solve that task at all in his case. Aug 25, 2013 at 20:52
  • RDBMS is not a solution for all but it became so because many have seen no alternative. SPs are hard to maintain, neraly impossible to refactor and very complex to develop, miss OOP and all programming principles at once. DBAs are happy to have that because they have jobs but this is changing and the change is fast. I am not sure if MS SQL has a CEO, I think Microsoft does. And neither Oracle or Microsoft are making most of their money on RDBMS, they are clever enough to have much broader product portfolio. Oct 10, 2013 at 21:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.