I read several articles informing that entity beans in a Java EE environment are considered as anemic (means only containing getters and setters without implementing behaviour).
What prevents me to put behaviour into entity beans ? So that session beans (stateless or stateful) could delegate all business logics to them (for logic making sense to be owned by entities).
I don't see why entity beans are necessarily anemic.
From a pure semantic perspective, you would expect an ENTITY bean to be a representation of an entity and its attributes. If you couple this with some logic, then you add additional responsibility to your entity class. And as we know from the Curly's law or the single responsibility principle, each class should do one thing and one thing only:
http://www.codinghorror.com/blog/2007/03/curlys-law-do-one-thing.html
http://en.wikipedia.org/wiki/Single_responsibility_principle
If you believe that you have a strong enough reason to violate this principle, you can, but as far in my experience, no reason was strong enough to violate standard software engineering practices, especially if you, like me, believe that the quality of software is best represented by the quality of its code.
There are no restrictions of implementing functionality on entity beans, but they're not meant to be used throughout your application so most of the time you'll add behaviors that modify entities on your Session Beans just because Session Beans are supposed to be accessed from the front end for example.
If we go deeper, session bean methods are usually decorated with transactional and security aspects while entity beans are not, so your application may not behave the expected way if you added code into entities.
Related
I have a Spring Boot application with a service that returns a Spring Data entity that is exposed to a controller. The problem is that I know it's not a good idea to use entities outside of DB transactions, so what would be the best practices?
Consider the following service:
#Transactional
public MyData getMyData(Long id) {
return myDataRepository.findById(id);
}
where MyData is a database #Entity and myDataRepository is a JpaRepository
This service method is called from a controller class, that sends this object in JSON format to a client that calls this method.
#RequestMapping("/")
public ResponseEntity<?> getMyData(#RequestParam Long id) {
return myService.getMyData(id);
}
If I expose MyData to a controller, then it will be exposed outside of a transaction and might cause all kind of hibernate errors. What are the best practices for these scenarios? Should I convert entity to POJO in side the service and return MyDataPOJO instead of MyData in MyService?
Using entities outside of transactions does not necessarily lead to problems; it may actually have valid use cases. However, there's quite a few variables at play and once you let them out of your sight things may and will go south. Consider the following scenarios:
Your entity doesn't have any relationships to other entities or those relationships are pretty shallow and eagerly fetched. You retrieve that entity from repository, detach it from persistence unit (implicitly or explicitly) and pass to controller. Controller does not attempt to modify the entity; it only serializes it into JSON - totally safe.
Same as above but controller modifies the entity before serializing it into JSON - again, totally safe (just don't expect those changes to be reflected in DB)
Same as above, but you've forgotten to detach the entity from PU - ouch, if controller changes the entity you may either see it reflected in DB or get transaction closed exception; both most likely being unintended consequences.
Same as above, but some of entity's relationships are lazy. Again, you may or may not get any exceptions depending on whether these lazy properties are being accessed or not.
And there are so many more combinations of intentional and unintentional design choices...
As you may see, things can get out of control very quickly. Especially so when your model has to evolve: before long you're going to find yourself fiddling with JSON views, #JsonIgnore, entity projections and so on. Thus the rule of thumb: although it may seem tempting to cut some corners and expose your entities to external layers, it's rarely a good idea. Properly designed solution always has a clear separation of concerns between layers:
Persistence layer never exposes more methods or entities than required by business logic. More over, the same table(s) can and should be mapped into several different entities depending on the use cases they participate in.
Business logic layer (btw this is your API, not the REST services! see below) never leaks any details from persistence layer. Its methods clearly define use cases from the problem domain.
Presentation layer only translates API provided by business logic into one or another form suitable for client and never implements additional use cases. Keep in mind that REST controllers, SOAP services etc logically are all part of presentation layer, not business logic.
So yeah, the short answer is: persistence entities should not be exposed to external layers. One common technique is to use DTOs instead; besides, DTO objects provide additional abstraction layer in case you need to change your entities but leave API intact or vice versa. If at some point your DTOs happen to closely resemble your entities, there are Java bean mapping frameworks like Dozer, Orika, MapStruct, JMapper, ModelMapper etc that help to eliminate the boilerplate code.
Try googling "hexagonal architecture". This is a very interesting concept for designing cleanly separated layers. Here's one of the articles on this subject https://blog.octo.com/en/hexagonal-architecture-three-principles-and-an-implementation-example/; it uses C# examples but they're pretty simple.
You should never leak the internal model to outside resources (in your case - the #RestController). The "POJO" you mentioned is typically called a DTO (Data Transfer Object). The DTO can be defined as an interface on the Service-side and implemented on the Controller-side. The Service would then - as you described - transform the internal model into an instance of the DTO, achieving looser coupling between the Controler and the Service.
By defining the DTO-interface on the service-side, you have the additional benefit that you can optimize your persistence-acces by only fetching the data specified in the corresponding DTO-interface. There is, for example, no need to fetch the friends of a User if the #Controller does not specifically requests them, thus you do not need to perform the additional JOIN in the database (provided you use a database).
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.
I am pretty new to Hibernate. I am having problem understanding these simple logics. I have understood that #Repository is used by Spring for accessing objects. Also, Hibernate uses #Entity to denote entities which are mapped into database tables. I was just wondering if a single class can be annotated with both #Repository and #Entity as they more or less imply the same.
NO.
Hibernate entities are managed by Hibernate ORM framework, they(and their proxies) are created by hibernate when you access them via get() or load(). They have a completely different (and complex) lifecycle than the Spring beans(they can be attached/detached/proxied/pending for removal)
Spring repositories are singletons, managed by Spring framework. Typically they exist as long as the container instance exists. New Hibernate sessions may be opened and closed, new user sessions engaged and then expired, but there still will be the same singleton instances of repositories.
Please see http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/objectstate.html#objectstate-overview for the possible hibernate object states.
As for the repository instances - typically they are stateless, as they are services.
RE: they more or less imply the same. No they are not the same. There was an old joke
How many C++ programmers does it take to change a light bulb? You're
still thinking procedurally. A properly designed light bulb object
would inherit a change method from a generic light bulb class, so all
you would have to do is send a light-bulb-change message.
But good OOP programmers do not think that way, according to single responsibility principle objects should should have a single reason to change. Repository works with the infrastructure and has nothing to do with the business rules. Infrastructure may change(you may need for example to store you object in XML instead of RDBMS), but this should not affect the classes encapsulating the state of business objects.
You can possibly mitigate this problem by making a reference from the entity class to an abstract repository interface(implement an infamous Active Record pattern - it will be like referencing some abstract bulb socket from the bulb, this does not seem to be a good solution because bulb sockets and bulbs have different lifecycles).
That is where High Cohesion principle starts to play, according to which it's just illogical for an object, whose role is to reflect the abstractions from the model, to perform some completely unrelated things like persistence or transmitting over the network. It's weird when Student class will have print(), saveToXml() or transmitByHttp() methods.
They don't imply the same thing at all.
#Entity
An #Entity is something that represents a "thing" in your business domain. It could be anything - a Customer, an Elephant, a Product. . . It will have attributes that will get persisted to the database as well as methods relating to those attributes (at least it should, unless it's an anaemic entity, but that's an anti-pattern. . . . later, when you're comfortable with the basics check out Spring's #Configurable annotation - this allows you to provide collaborators to your entity).
#Repository
A #Repository, on the other hand provides an interface for retrieving and storing those entities.
There are some frameworks, especially in other languages, that combine the persistence and entity attributes on the same object, however this is not common in Java/Hibernate/Spring.
I'm in the process of designing part of my companies architecture for its Java EE web applications. I'm pretty clear on the reasons to use a façade and one or more DAOs. The problem I have is this:
There will be some logic that definitely belongs in the integration tier because it's all about keeping the data model consistent. Except the logic goes beyond simply maintaining referential integrity and other 'raw' persistence tasks which will be handled by JPA and Hibernate. I don't class this as business logic because it's separate to any business function. However, my understanding is that a DAO should only implement the logic required to access and persist objects to the data source.
My conclusion is that I need a 'business object'-like pattern which is appropriate for the integration tier. I've looked around and the closest thing I have found (yet still not quite right to my mind) is the Sun Transfer Object Assembler pattern.
Either there's a gap in my understanding of Java EE or there is a pattern out there that will fit.
maybe a mediator is what you want:
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
then you can use a DaoMediator in order to coordinate two or more DAOs
It sounds to me like you may be missing a controller, and consequently may need the MVC pattern. The controller will look after the DAOs and present a consistent view (don't think in terms of GUIs, burt rather some client-facing interface). When modifications are made via this view, then the controller coordinates the changes to the model via the DAO. I suspect that your facade objects may be the view in this scenario.
Having said this, I wouldn't worry too much about identifying particular patterns. You often find that taking into account all your requirements and separating concerns where applicable, that you end up implementing a particular pattern and only identify it as such after the fact.
Have you considered using aggregates from Domain Driven Design?
I'm a student of DDD myself and it seems the business logic you're trying to design could be accomplished by richer POJO-like domain models. You'd have each
domain object to be responsible for its aggregate objects, and also including any logic concerning that business concept; that said, your integration layer would coordinate those rich objects but would refrain from having real logic per se (i.e several conditional logic).
Perhaps the pattern you're trying to find is actually a step into richer domain objects?
I think it's a DataMapper (or Adapter) pattern between your DAL and your Business Layer, but without a more concrete understanding i couldn't be sure.
What is driving the requirement for consistency between the DAOs? If there is some business assumption that is dictating the relationship. For example, you might have an invoice type that when it is 'Capital' then we have to make sure several other objects are in the right state or have the right set of values. This is definitely outside the realm of the data-layer.
I wouldn't try to hard to find the perfect pattern for this case. You need some sort of coordinating class though, a mediator or controller of some sort.
I used to design my application around anemic domain model, so I had many repository object, which were injected to the big, fat, transaction-aware service layer. This pattern is called Transaction script. It's not considered a good practice since it leads to the procedural code, so I wanted to move forward to the domain driven design.
After reading couple of articles on the web, listening to the Chris Richardson's talk on Parleys and reading DDD chapters of the POJOs in Action, I think I got the big picture.
Problem is, that I don't know, how to organize transactions in my application. Chis Richardson in his book states:
The presentation tier handles HTTP requests from the user’s browser by calling
the domain model either directly or indirectly via a façade, which as I
described in the previous chapter is either a POJO or an EJB.
Good so far, but Srini Penchikala on InfoQ article states:
Some developers prefer managing the transactions in the DAO classes which is a poor design. This results in too fine-grained transaction control which doesn't give the flexibility of managing the use cases where the transactions span multiple domain objects. Service classes should handle transactions; this way even if the transaction spans multiple domain objects, the service class can manage the transaction since in most of the use cases the Service class handles the control flow.
Ok, so if I understand this correctly, repository classes should not be transactional, service layer (which is now much thinner) is transactional (as it used to be in Transaction script pattern). But what if domain objects are called by presentation layer directly? Does it mean, that my domain object should have transactional behavior? And how to implement it in Spring or EJB environment?
This seems kind of weird to me, so I'd be happy if somebody would clarify that. Thank you.
My personal take on applying DDD with Spring and Hibernate, so far, is to have a stateless transactional service layer and access the domain objects through that. So the way I'm doing it the domain model does not know about transactions at all, that is handled entirely by the services.
There is an example application you might find helpful to take a look at. It looks like Eric Evans was involved in creating it.
See this extremely useful blog-post. It explains how to achieve smooth DDD while not loosing Spring's and JPA's capabilities. It is centered around the #Configurable annotation.
My opinion on these matters is a bit non-popular. Anemic data model is actually not wrong. Instead of having one object with data+operations, you have two objects - one with data and one with operations. You can view them as one object - i.e. satisfying DDD, but for the sake of easier use they are physically separated. Logically they are the same.
Yes, this breaks encapsulation, but it doesn't make you use some 'magic' (aop + java agent) in order to achieve your goals.
As for the transactions - there is something called Transaction propagation. Spring supports it with #Transactional(propagation=Propagation.REQUIRED).
See this, point 9.5.7. In case you want your transactions to span multiple methods (of multiple objects) you can change the propagation attribute accordingly.
You can also use #Transactional in your service layer, where appropriate, but this might introduce a lot of boilerplace service-classes in cases when you want to use simple, single-step operations like "save".
I think one easy way to get started with DDD and Spring and have good examples of how to deal with transactions is by looking at one of the sample apps that get shipped with Spring Roo. Roo churns out code that follows the DDD principles. It relies heavily on AspectJ. I suspect it was implemented building on the ideas put forward (back in 2006) by one of SpringSource's heavyweights, Ramnivas Laddad, in this talk.
Unnfortunately I haven't make myself familiar with Spring but I will give feedback about your DDD understanding. Reading your description of transaction it is obvious that you haven't understand DDD especially Aggregate, Aggregate Root, and Repository concept.
In DDD transaction can't span across aggregates so one Aggregate will always have one transaction.