views:

224

answers:

6

I'm designing an application that will allow putting some data in the database. I wanted to somehow reflect the database structure in the application, for example if i have a table where there are departments and a table with employees and there is a department with id 3 and two employees related to him with ids 44 and 123, in my application there would be a class Department with a property Id set to 3 and it would have a reference to two Employee classes with Id's set to 44 and 123.

I talked to my coworker about it and he said that i shouldn't be reflecting the database structure in the application - the application should know nothing about the data source. it sounds quite clever but if i won't have Id properties in my classes (and they certainly reflect the database structure) it's impossible that I could know which employee's properties were changed and I won't be able to put data back in database. I'm confused - I've heard about frameworks to reflect database structure as objects (hibernate for example) and I'm not really sure if it is so bad.

what do you think?

A: 

What you are looking for is a Object Relational Mapper. That is a framework for automatically taking care of pushing data between your database and your objects.

David Schmitt
A: 

Applications should reflect user needs/ user stories. Database should be logical data storage for your applications.

aivarsak
+6  A: 

Well, I would offer that the point of ORM frameworks (like Hibernate) is to decouple the database structure and the object model, not to promote their sameness.

There are different philosophies about how to design object models and database schemas, depending on who you talk to. Many app developers see the DB as basically a bit bucket and let the needs of the app drive the design of the DB schema. So for example app developers may be fine allowing the idiosyncracies of a given ORM framework to impose upon the DB schema design, they may be fine denormalizing something in cases where DB developers wouldn't want to, etc.

On the other side, the DB developers often take the DB to be more fundamental, and not without good reason: oftentimes many apps need to work against a single DB, the DBs typically outlast the apps, the data is more valuable than apps, stuff like that. So they'll put up a pretty good fight if your argument is "well, Hibernate requires such-and-such..."

I think both camps will agree though that there's no need--or even desire--to strive for a 1-1 relationship between classes and tables. Relationships between classes that work fine in the app world can turn into joins that don't perform well at all in the DB world, say. There are for instance different ways to map class inheritance to a DB schema, and the proper choice there is dependent upon normalization and performance concerns, not by a blind mandate to get the class/table mapping to be 1-1. You may have components that don't have their own independent lifecycle (for example, an Address that exists only in relationship to some User, say), and a lot of times people will just map that to a list of columns in a user table instead of making it a first-class entity in its own right, thus saving a join, thus emphasizing its non-freestanding nature, etc.

Willie Wheeler
A: 

I know I don't need to exactly reflect the database structure (especially if it doesn't help the application) but in the example I've provided there is no other way I can think of that will allow me identifying which employee record was changed inside the application and which data W need to change in the database - am I right?
I mean - is it a bad idea that my Employee class will have it's ID property and that this Id is the record's id in the database?

Not in my book. Domain objects can have IDs too, especially entities. Why couldn't you consider the DB-provided ID to be the domain object's ID? The DB is just storing that. Doesn't matter where it came from; call it the object's ID...
Willie Wheeler
+1  A: 

Ideally your application does not need to know anything about how objects are stored (if they are stored at all). But most of the time, you need to persist the objects between sessions and you need some sort of Object Persistence, that can be implemented manually or through an OPF (Obj Persistence Framework).
Often it will be a relational DB and the objects relation that you describe can be implemented with a simple Master Detail case where the DeptId is a Foreign key in the Employee table to join it to the Department Table, or it can be a relation Table EmpDept holding all the associated EmpId and DeptId.
This physical implementation detail can be hidden to the business logic, but you still need to know that an employee belongs to a department anyway.
So your coworker was not really right because you need to know that an employee holds the Dept_Id it belongs to.

François
and that is what i really wanted to know - i can't escape from knowing that an employee belongs to the certain department and i must be able to identify which employee and which department
+1  A: 

Willie's answer was quite good. Personally, I prefer using databases as a bit bucket. My hint is this: If you really want to have your data models and your object models to be the same - and there is absolutely wrong with them being the same! use an object database. Becacuse, in this case, the relational layer won't buy you too much.

If you choose an ActiveRecord-style object database, (like SandstoneDB) what you do is this: you make your domain object without spending a thought about data storage. When your object works fine, you send it the "save" message, and it writes itself into the database. That's it. No configuration! It will automatically generate its own id, and with this you can retrieve it fast from the database.

If you go the classic way and use an RDBMS, you can step away from your database design, but why should you? You didn't design your tables for fun. Some tools will autogenerate objects out of table definitions: that's fine. They usually provide a good start. If there's something wrong, you can change only the objects, or only the data definitions, or both. Just look at your code and see what is more convenient.

Niko

nes1983