Hibernate (best)most common structure - java

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.

Related

Best practices to separate concerns when accessing database

I've been trying to improve the separation of concerns when it comes to applications that access a database (via Hibernate).
On one of the applications I've been using the following approach:
Create services with business logic that have no connection/awareness of the database. They only communicate with GeneralDAO (and with other services);
A GeneralDAO responsible for CRUD/find operations, and with methods that involve more complex database queries.
The problems I see with this approach are:
GeneralDAO slowly becomes a God Object, when your application grows and require lots of specific database queries.
Sometimes the more specific Services become only proxies to the GeneralDAO, since the method is simple and only requires a database query. See example 1.
Example 1: Service is just a proxy
BookService manages things related to books in the Library application. Let's consider 2 methods:
archiveBook(Book)
findByIsbn(String isbn)
In archiveBook(Book) there might be considerable business logic involved - we might imagine this involves calls to:
distributionService.unbox(Book);
archivalBook.archive(Book);
librarianService.informNewBook(Book);
But findByIsbn(String isbn) is a lot more simple: it just needs to execute an SQL call to the database. So in this case I see two options:
Redirect the call to an object that can speak to the database to execute the query. For example generalDAO.findByIsbn(String isbn), that uses a db communication layer (in Hibernate it would use a sessionFactory or EntityManager) to execute the query.
Make that database layer available to the BookService, so that it executes the query itself
Questions/opinions (first number identifies the option above):
1.1. Isn't it strange to have 2 methods with the exact same signature, even if this is done to keep the BookService independent of the database layer (and ORM)?
1.2. How do you suggest avoiding The God anti-pattern? Would you suggest breaking the GeneralDAO into several DAOs depending on what the methods do? In this case, won't we risk needing to inject lots of DAOs into some Services, leading to a Service having too many objects injected into it?
2.1 What do you think of this alternative? Doesn't it break the "separation of concerns" by having the BookService be aware of objects at two different levels of abstraction (the DAO and the sessionFactory/EntityManager)?
3.1. Would you suggest any other approach/pattern/best practise?
Thanks!
1.2. How do you suggest avoiding The God anti-pattern? Would you suggest breaking the GeneralDAO into several DAOs depending on what
the methods do? In this case, won't we risk needing to inject lots of
DAOs into some Services, leading to a Service having too many objects
injected into it?
Generally, a DAO class should handle a specific entity.
If one of your entities require many kinds of queries, you could divide it again into two or more DAOs by grouping them by common concern (for example : reading, writing, selecting on agregates, etc...) as you said.
If you have too many queries and too many DAO, maybe, you should check if you don't write almost the same queries in several methods. It it the case, use specification or Criteria API to allow the client to custom queries by parameters. If the queries are really different, you have various processings. So, using multiple DAOs seems a suitable solution. It avoids increasing the complexity and the rise of god objects.
1.1. Isn't it strange to have 2 methods with the exact same signature, even if this is done to keep the BookService independent of the
database layer (and ORM)?
When you divide you app in logic layers, as you noticed, in some operations, some layers perform only delegation calls to the below layer. So in these cases, it is rather common to have method names which are the same. I would go further : it is a good practice to have the same name if it is just delegation call. Why do we create a variation in the conveyed behavior if they both address the same need?
2.1 What do you think of this alternative? Doesn't it break the "separation of concerns" by having the BookService be aware of objects
at two different levels of abstraction (the DAO and the
sessionFactory/EntityManager)?
BookService depends on DAOs but should not depend on sessionFactory/EntityManager which makes part of the DAO implementation.
BookService calls DAO which uses a sessionFactory/EntityManager.
If necessary, BookService may specify transactional details on itself or on its methods with #Transactional annotation.
3.1. Would you suggest any other approach/pattern/best practice?
As you use Spring, try to rely on the Sping JPA repository (less boiler plate to handle for common cases and extensible class)
Using specification or criteria patterns when you have several variants of some queries.

Extra actions in a setter of a hibernate entity

I'm working on a legacy project with hibernate. Occasionally I find code where the developers wrote extra code in the set methods of entity objects. I'm wondering if this is an accepted practice ? Shouldn't hibernate entity objects just be pojo classes with extra annotations and maybe a few #Transient helper methods ?
If you want to do extra actions isn't that the responsibility of the service/dao working with the entity ?
What is the best practice ? Does anyone know of a blog or recognized article explaining this ?
IMHO, both approaches are correct. They both have its pros and cons. This is related to the everlasting Anemic model vs DDD (Domain-driven design) war.
Regarding Hibernate, it is quite flexible. It lets you took either approach you want. Performance and correctness of the solution don't depend on the decision you take, but on the correctness of the queries, database indexes, fetching strategies for entities, chosen algorithms, I/O handling, concurrency implementation, transaction management, etc.
If you go by DDD, the entities would be part of the business layer, while Hibernate itself (Session, SessionFactory and the whole ORM) would be part of the persistence layer. In this case, the entities would contain annotations related to persistence, which would be just hints for the ORM.
You should also be careful with transaction management. This is better accomplished outside of the entities. (Actually, one main advantage of the anemic model is that transaction management is very easy, because you wrap every service method of your business layer inside a transactional unit).
As you've mentioned you have a mix of both "ideologies", maybe you could use that fact as an advantage: let service methods delegate the logic to domain entities, but keep transaction management in your business services.

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.

Using DAOs with composite Objects

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.

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