Using DAOs with composite Objects - java

I am trying to rewrite a bunch of DAOs here is the setting:
only plain JDBC (no JPA, ORM whatsoever)
no interfaces used
lots of checks before inserting an object
Business objects are strongly linked
My main question is:
How do I persist/retrieve a business object that is composed of multiple other objects?
e.g. does my CustomerDAO know the AddressDAO and retrieve the csutomers adresses from there?

only plain JDBC (no JPA, ORM whatsoever)
Business objects are strongly linked
Not sure why you don't want to use JPA while you want your business objects to be linked, but at least you should use Spring JDBC template that would relieve you from some boilerplate code.
Regarding the other constraints, I would do it as follows:
I would still employ interfaces to define the DAO methods and implement them in a Spring JDBC template backed DAOImpl. Use the DAO everywhere and inject the DAOImpl.
My DAOs will be simply one-to-one mapping to the underlying tables and each DAO wouldn't know about the existence of other DAOs.
My Manager layer will have all the business logic that runs validation checks and prepares the set of objects that need to be persisted, calls the appropriate DAO and appropriate method (CREATE/UPDATE/DELETE) to persist the objects.
Again, the Manager layer will follow the interface-based implementation and the view layer would have manager types injected with the ManagerImpls.
My two cents!

You may Consider Using JOOQ. It is not JPA, but it may easily be used as an alternative solution. It is lightweight enough. It also provides provides a reverse engineer tool, where it builds your Database entities as DAO objects.
I have embed JOOQ in a relevant situation, where the application was fairly engineered designed. I didn't use its DAO functionality, rather than using it as a higher layer to avoid messing with JDBC Layer.
Cheers!

Composite entities are a layer above DAO's. If you want to remove ALL coupling, domain objects persisted by DAOs should be flat without relationships. See Core J2EE patterns CompositeEntity.
Also, it's a good idea not to introduce coupling inbetween the DAO's by putting finders for one in the other. E.g.:
AddressDAO.findForCustomerId(id);
is inferior to using a third DAO to manage the relationship. I.E:
CustomerAddressRelDAO.findAddressForCustomer(id);
If you use a relationship DAO neither address nor customer are dependent on (or aware of) each other.

Related

JPA annotations in entity layer according to Uncle Bob

According to Uncle Bob, the entity layer should know nothing about the database.
What about the JPA annotations then? Don't they violate the architecture proposed by the author? If they do, how to use the entities with JPA?
In a non-ORM world, a clean architecture would (or could) involve having DAO interfaces, with DAO implementations knowing how to retrieve the data from a database (or any other source), and convert and return it as a domain object. An upper layer would then use the DAOs (through the interfaces) to retrieve those objects.
This would allow you to for example create different DAO implementations for different databases, and you could change databases without bothering the rest of the software.
In a JPA/ORM world you can bypass a lot of that if you choose. You can use entity classes as domain objects, create the entity classes in a database agnostic way (i.e. not using any database specific NativeQueries for example). Now that your entities are database agnostic, you can just use NamedQueries in your service layer instead of creating DAOs.
In the end you need to have some layer which knows about the database, but in JPA's case it doesn't even hold true. Your entities are Java objects and it's the JPA implementation layer that is responsible for converting them to and from the database.
In conclusion: there are very few universal truths in software development and you can talk to a dozen uncles and hear a dozen versions of essentially the same "story".

Convert hibernate orm entities into complex objects and vice versa

I'm new to ORM and hibernate.
my application is of complex design pattern. with builders, fluent interface.
and those objects also throws exceptions while creating illieagel objects. and I use orm mapping to access database. I convert those ORM entities to my complex objects and vise versa. is it good idea or any other alternate.
As a general rule, you should create business objects (in your case they exist already) when you truly need them. So, if your application needs those complex objects, that is fine (but keep in mind that they are hard to maintain as you will have to change a bunch of objects when you make a change in your database and Hibernate objects).
If you could get rid of those complex objects, you could use Hibernate's detached entities as simple DTOs all over your application and you won't have the difficulty of maintaining two sets of objects. On the other hand, using business objects can make your web layer (or other layers) independent of Hibernate and its entities, so makes your life easier if somehow in the future you decide not to use Hibernate. From my experience, if the recent is not your case and you are thinking of Hibernate as a long term solution, using Hibernate's detached entities is a much easier solution.
Do you have some requirements which says that you need two kind of entities: those rich/complex and those ORM based?
I used ORM along with domain driven design and it worked fine. We decoupled rich entities (and value objects) from services and those entities were persisted from aggregate downwards.
You certainly must slightly change those entities when you want to use hibernate mapping but I haven't find anything which would break our DDD model. E.g. parameterless constructor can be private etc.
As we used fluent/xml mapping, model was completely separated from persistence layer, see term persistence ignorance

May Service annotated classes contain SQL/HQL in spring framework?

i examine lots of samples but i didn't find an adequate solution for this.
Some documents say "Ideally your business logic layer shouldn’t know there is a database. It shouldn’t know about connection strings or SQL."
I found some samples which locate the business logic to #Service annotated classes but they use SQL/HQL in #Service methods.
What should be the ideal usage? If we want to change database or persistence technology should we change only #Repository annotated classes or both of them?
I prefer putting all persistence-related stuff (i.e. queries, and everything dealing with JDBC, JPA or Hibernate) in a DAO layer, and have the service layer rely on this DAO layer for persistence-related stuff.
But the main goal is not to be able to change the persistence technology without affecting the service layer. Although that could be possible if you switch from Hibernate to JPA, for example, it wouldn't be if you switch from JPA to JDBC, for example. The reasons are that
JPA automatically persists all the changes made to entities without any need for update database queries , whereas JDBC doesn't, and thus needs additional update queries
JPA lazy-loads association between entities, whereas JDBC doesn't
...
So changing the persistence technology will affect the service layer, even if all the persistence stuff is isolated in DAOs.
The main advantages of this decoupling, IMHO are
clearer responsibilities for each class. It avois mixing persistence-related code with business logic code.
testability: you can easily test your service layer by mocking the DAO layer. You can easily test the DAO layer because all it does is executing queries over the database.
In your service methods you shouldn't use any SQL/HQL syntax or any database work. All of them should be in DAO layer which are annotated as #Repository. You should just call them from your service methods. In this way, you can easily change your db in future. Otherwise, it would have too much burden
Ideally your business logic deals with or consists of objects that model the domain. It shouldn't be aware of the issues of persistence etc. . That's what O/R-Mapper like hibernate are all about. The business logic demands required objects, based on domain attributes (like Employee name, last month's revenue ...).
The persistence layer should be able to translate the business demands into SQL/HQL/Service calls or whatever the used technology requires. Therefore the business logic layer only changes when the business logic changes.
That would be the goal in an ideal world, but in reality it won't work for non-trivial problems. You can't avoid some degree of coupling. But as #JB Nizet said, it pays off to reduce the coupling to a reasonable amount. Using TDD and adhering to OO principles like SRP will help you get there.

Hibernate (best)most common structure

I have a POJO class with hibernate annotations for each table in database. Also have one HibernateUtility for my database, which creates SessionFactory.
Should I create a manager per DB table or manager per DB?
Under manager I mean a class, which does all the transactions, CRUD.
Which gives me the best performance?
It's usually helpful to have a DAO per table. You don't need to write a lot of code, as you can use a generic dao.
Performance wise: remember that you're using hibernate, which down't have performance as one of its pillars, but hibernate usually brings down development time. If you need performance try using myBatis or just plain jdbc.
Performance has nothing to do with the number of classes you have.
A manager per DB table is too many: business use-cases typically involve more than one table.
A manager for the whole database is too few: having all the business logic of an application in one class is not maintainable.
An application typically has groups of use-cases: user management, notifications management, etc. I would use these as a way to split the logic into classes.
Also, note that business logic (which is what I assumed would be in your manager classes) should be separated from data access logic (DAOs, repositories). The CRUD is typically the responsibility of the DAO, whild the business logic and transaction demarcation is done in the service (manager) layer.
I prefer to have a DAO class for each table in the DB. I actually have an abstract DAO object which does all the usual CRUD operations and then I'll override or add additional query methods as they are needed. I wouldn't be able to re-use my CRUD logic if it was all in one DAO.
Actually, I'm surprised there is not a standard abstract CRUD implementation out there that everybody uses - it's trivial to write (maybe there is a well maintained one?). My generic DAO also has convenience methods for obtaining the EntityManagerFactory - useful in a Java SE environment where these sorts of things are not injected.

About Data Objects and DAO Design when using Hibernate

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!
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.
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 :-)
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.

Categories