Ruby on Rails has polymorphic relations which are really useful for implementing functionality such as commenting, tagging and rating to name a few. We can have a comment, tag or rating class which has a many to one polymorphic relationship with a commentable, taggable and rateable object. Also, a given domain object can choose to implement any combination of such relations. So, it can for example be commentable, taggable and rateable at the same time.
I couldn't think up of a straightforward way to duplicate this functionality in Hibernate. Ideally, there would be a Comment class which will have a many to one relationship with a Commentable class and a Commentable class will conversely have a one to many relationship with Comments. It will be ideal if the concrete domain classes can inherit from a number of such classes, say Commentable and Taggable. Things seem a little complicated as a Java class can only extend one other class and some code might end up being duplicated across a number of classes.
I wanted to know what are the best practices for modeling such relationships neatly and concisely using Hibernate?
It seems to me that your question is not hibernate specific but more on the lines of "how can I get around the single inheritance model?"
If implementing interfaces is not what you have in mind AOP (Aspect Oriented Programming) might provide a way for you to do what you wish.
Related
I'm currently working on improving some old uni assignments moving them from serializable files to any other form of storage, mainly SQL Databases.
I understand the concept of relational database design and the similarities with OOP Classes, however, I'm not entirely sure how to approach this issue from an OOP design perspective.
Right now I have a Hotel class with a List of Rooms as property, each Room has a list of Guests as property (full code here)
Back when using files I could mark these classes with the Serializable interface and store the parent object in a single file. But when using relational DB, I store each list as a single table and use separate queries to obtain the corresponding results. Same goes for the add() operation: with databases, I can do something like Guest.add() and add all the required fields directly to the database, whereas with my current design I need to call Room.getGuestList().add() (or a similar approach).
I totally understand that neither of both approaches is ideal, as both classes should be only worried about storing the data and not about the implementation of an add method, but even if I separate this in a single class, shall I still define a List property within each class?
I'm pretty sure I'm missing a design pattern here, but I cannot find the one that would solve this problem or maybe it's just that I've been taught wrong.
Thanks for your answers
Edit: I've decided thanks to the answers provided to transform my implementation following the DAO pattern as explained in this question and the Oracle documentation.
Normally you would have 3 tables: hotels, rooms, guests.
Rooms would have relation to hotel (hotel id) and guest would have relation to room(room id). That's it.
Those relations can be easily reflected in OOP using some sort of ORM. JPA with Hibernate is an excellent example. Check that out. You will be able to get hotel, its rooms and all guests of hotel just like you described without using a single SQL query in your code.
I need to generate and then perform a complex sql-query which is going to access multiple databases to create some general report. This implies that the query's not related to a specific DAO object.
So where should I put the logic of executing such a query and returning result as DTO? If I create ReportDao interface and then implement it it may lead another developer into troubles, beucasu I think they will expect the Dao object tied with some table in the database.
!Opinion warning!
A DAO does not necessarily have to be linked to a specific domain class. No domain class lives in isolation, and if one presumes a DAO to only include operations on one table/domain class, one is in for a surprise, since operations might pertain to multiple domain classes, and thus be wrongly placed no matter where you put it. It's better to also think of a DAO as a collection of methods pertaining to a certain area of functionality. If most Dao are modeled around domain objects it might be wise to name the different one a bit differently, but ReportDao should be fine as long as we're talking about a collection of methods pertaining to reports/reporting. Or maybe "GeneralReportDataDao" is better (keep in mind that I only have the information in your question to work with, think about what the class represents and try to find a descriptive name..)
Another point I have seen from experience when organizing DAOs after domain classes, is that the DAOs pertaining to central domain classes tends to grow very large, since central domain classes are often linked to large amounts of functionality. This is not only true for DAO-classes, but also for Services, etc, using the same pattern for organizing functionality.
We mainly have two "types" of classes in Java, we have classes that represent something (classes containing data, typically stateful classes), and classes that do something (service, dao, etc, typically stateless classes). The stateful data classes should be named and modeled after what they represent, i.e. the data, while the stateless service classes should be named and modeled after functionality. While it is tempting to try to organize services the same way as data, it often leads to poor code, with large classes and areas of functionality spread across several classes.
I am trying to figure out best practice for N-Tier application design. When designing the objects my UI needs and those that will be persisted in the DB some of my colleagues are suggesting that the objects be one in the same. This doesn't not feel right to me and I am ultimately looking for some best practice documentation to help me in this decision.
EDIT:
Let me clarify this by saying that the tables (Entity Classes) that are in the DB are identical to the objects used in the UI
I honestly do not understand why I would want to design this way given that other applications may want to interact with my Data Access Layer....or it is just ignorance or lack of understanding on my part.
Any documentation, information you could provide would be greatly appreciated. Just want to better understand these concepts and I am having a hard time finding some good information on the best practice for implementing these patterns (Or it is right in front of me on what I found and I didn't understand what was being outlined).
Thanks,
S
First of all, DAOs and database entities are two very different things.
Now to the question. You're right. The database entities are mapped to a database schema, and this database schema should follow the database design best practices, and be normalized. The UI sometimes dislays exactly the information from a given entity, but often show data that comes from multiple entities, in an aggregate format. Or, to the contrary, they only show a small part of a given entity.
For example, it would make sense for a UI to show a product name, description and price along with the name of its category, along with the number of remaining items in stock, along with the manufacturer of the product. It would make no sense to have a persistent entity containing all those fields.
In general and according to most "best practices" comments, yes, those two layers should be decoupled and there should be separate objects.
BUT: if your mapping would only be a one-to-one-mapping without any further functionality in the non-database-object, why introduce an additional object? So, it depends. (as usual ;-) ).
Don't use additional objects if the introduced overhead is bigger than the gain. And don't couple the two layers if re-usability is a first-class-goal. That may not be the case with some legacy applications, e.g.
I am learning hibernate an I came across Hibernate Mapping Component.
Why should we use it if we can have the same pojo class for student and address?
You can. But that doesn't mean you want.
Reason one: you want to model them differently
In objects you want to model something the best possible way. That means one thing are Students and other Addresses. In a future you could have more Address per student, or none, so migration to that model will be easier if you have two differents objects.
Think of it as high cohesion and low coupling (good design patterns). Each class has its meaning, its responsability, its limited range of action. The more isolated classes are, the more punctual changes will be. The more modular your code will be too.
By contrast, in tables you make concessions in order to gain performance and more direct queries. That means you can denormalize your model (like joining students and addresses).
Reason two: legacy models
By example. If you have a legacy single table and want to use two objects, you need this mapping. Or... if your application is already made, based on two objects, but your database is reengineered and you decide one table is better.
One more point is that Address (which is treated as component here) cannot have its own primary key, it uses the primary key of the enclosing Student entity.
I have had similar questions and concerns as to how to convert between Hibernate entities and data transfer objects to be returned by a web service as are discussed in this question:
Is using data transfer objects in ejb3 considered best practice
One of the factors mentioned here is that if the domain model changes, a set of DTOs will protect consumers in the case of a web service.
Even though it seems like it will add a substantial amount of code to my project, this reasoning seems sound.
Is there a good design pattern that I can use to convert a Hibernate entity (which implements an interface) to a DTO that implements the same interface?
So assuming both of the following implement 'Book', I would need to convert a BookEntity.class to a BookDTO.class so that I can let JAXB serialize and return.
Again, this whole prospect seems dubious to me, but if there are good patterns out there for helping to deal with this conversion, I would love to get some insight.
Is there perhaps some interesting way to convert via reflection? Or a 'builder' pattern that I'm not thinking of?
Should I just ignore the DTO pattern and pass entities around?
Should I just ignore the DTO pattern
and pass entities around?
My preference is usually "yes". I don't like the idea of parallel hierarchies created just for the sake of architectural or layer purity.
The original reason for the DTO pattern was excessive chattiness in EJB 1.0 and 2.0 apps when passing entity EJBs to the view tier. The solution was to put the entity bean state into a DTO.
Another reason that's usually given for creating DTOs is to prohibit modification by the view layer. DTOs are immutable objects in that case, with no behavior. They do nothing but ferry data to the view layer.
I would argue that DTO is a Core J2EE pattern that's become an anti-pattern.
I realize that some people would disagree. I'm simply offering my opinion. It's not the only way to do it, nor necessarily the "right" way. It's my preference.
There needs to be a contrarian view amongst all the jolly kicking of the DTO.
tl;dr - It is sometimes still useful.
The advantage of the DTO is that you don't have to add a zillion annotations to your domain classes.
You start with #Entity. Not so bad. But then you need JAXB so you add #XMLElement etc - and then you need JSON so you add things like #JsonManagedReference for Jackson to do the right thing with relationships then you add etc. etc. etc. ad infinitum.
Pretty soon your POJO ain't so plain any more. Read about "domain driven design" sometime.
In addition you can "filter" some properties that you don't want the view to know about.
We should not forget that entity objects are not easy to handle when they are in managed state. This makes their passing to GUI forms problematic. To be more precise, child objects are handled eagerly. This cannot be done out of session, cousing exceptions. So, they either have to be evicted (detached) from the entity manager of they have to be converted to appropriate DTOs. Unless of cource there is a pattern, which I am not aware of, that I would be very glad to know.
For quickly create a "look-alike" DTO, without a bunch of duplicate get/set code, you can use BeanUtils.copyProperties. That function help you quickly copy the data from DAO to DTO class. Just remember that there are more than one common libraries support BeanUtils.copyProperties, but their syntax are not the same.
I know this is an old question, but thought I would add an answer offering a framework to help in case someone else is tackling this problem.
Our project has JAXB annotated POJOs that are separate from the JPA annotated POJOs. Our team was debating how best to move data between the two objects (actually data structures).
Here is an option for people to consider:
We found and are experimenting with Dozer which handles (1) same name, (2) XML mapping and (3) custom conversions as ways to copy data between two POJOs.
It has been very easy to use so far.