tags:

views:

183

answers:

3

I'm hesitating between two designs of a database project using Hibernate.

Design #1.

(1) Create a general data provider interface, including a set of DAO interfaces and general data container classes. It hides the underneath implementation. A data provider implementation could access data in database, or an XML file, or a service, or something else. The user of a data provider does not to know about it.

(2) Create a database library with Hibernate. This library implements the data provider interface in (1).

The bad thing about Design #1 is that in order to hide the implementation details, I need to create two sets of data container classes. One in the general data provider interface - let's call them DPI-Objects, the other set is used in the database library, exclusively for entity/attribute mapping in Hibernate - let's call them H-Objects. In the DAO implementation, I need to read data from database to create H-Objects (via Hibernate) and then convert H-Objects into DPI-Objects.

Design #2.

Do not create a general data provider interface. Expose H-Objects directly to components that use the database lib. So the user of the database library needs to be aware of Hibernate.

I like design #1 more, but I don't want to create two sets of data container classes. Is that the right way to hide H-Objects and other Hibernate implementation details from the user who uses the database-based data provider?

Are there any drawbacks of Design #2? I will not implement other data provider in the new future, so should I just forget about the data provider interface and use Design #2?

What do you think about this? Thanks for your time!

A: 

I recommend design #2. Simply construct domain objects, and let hibernate look after them. Don't write separate classes that are persisted.

Hibernate tries to hide most of the persistence business from you. You may need to add a few small annotations to your entities to help it along. But certainly don't make separate classes.

You may need some very small DAO classes. For example, if you have a Person entity, it would be fairly common practice to have a PersonDAO object that saves a person. Having said that, the code inside the DAO will be very simple, so for a really small project, it may not be worth it. For a large project, it's probably worth keeping your persistence code separate from your business logic, in case you want to use a different persistence technology later.

John
I have a few concerns about to map domain objects directly to Hibernate. (1) If I want to use annotation, I need to put Hibernate annotations in domain objects, but these domain objects are used in many many other components in the system. I don't think the user of domain objects should see Hibernate-specific stuff in the code. (2) Conflicts between H-Objects and domain objects. For example, some H-Objects need "id" field, but domain objects do not. H-Objects needs getter/setter, but domain objects can have all "final" fields.
X. Ma
+1  A: 

Hibernate Domain objects are simple POJO so you won't have to create separate DPI-objects, H-Object themselves can be used directly. In DAO you can control whether they come from hibernate or anything else.

tech20nn
Agreed. I always add a copy-constructor to my data objects to make thing easier.
Maurice Perry
A: 

I highly recommend reading Chapter 4 "Hitting the database" of Spring in Action, 3rd edition, even if you aren't using Spring in your application. Although my second recommendation would be to use Spring :-)

The DAO pattern is a great way to keep database and ORM logic isolated in the DAO implementation, and you only need one set of entity objects. You can make that happen without Spring, it just takes more work managing your sessions and transactions.

If I understand your post, this is sort of a middle-ground between Design 1 and Design 2. The H-Objects (the entities that Hibernates loads and persists) don't need any Hibernate specific code in them at all. That makes them perfectly acceptable to be used as your DPI-Objects.

I've had arguments with folks in the past who complain that the use of JPA or Hibernate Annotations exposes Hibernate specifics through the DAO interface. I personally take a more pragmatic view, since annotations are just metadata, and don't directly affect the operation of your entity classes.

If you do feel that the annotations expose too much, then you can go old school and use Hibernate Mappings instead. Then your H-Objects are 100% Hibernate free :-)

dave
Thanks for the answer, Dave. This seems to be the most widely adopted approach. As in my reply to John's answer, a few things about this approach bug me. Anyway, I think I'm going to use this while looking for a perfect solution. :)
X. Ma