I can't seem to find the correct wording to search the web and get the right answer. So, every time I have an object that has a collection of other objects I get stuck on figuring out how to design the relationships.
For instance, a very rudimentary example would be..
So, I have a Person who can have many addresses. I know it would be incorrect to have the PersonDAO also create Addresses and put them in the Person object so how would I go about having one method (listAll()) for Person objects but have them come back with all of their addresses as well?
I hope this makes sense, please let me know if I need to clarify.
Also, the only thing I could find online that looked somewhat accurate was to use a CollectionsDAO but I wasn't sure how that would work so I threw it in there in red.
One solution would be to have the PersonDAO call the AddressDAO to get the Addresses and put them in the Person object(s) it returns. This would go inside a separate listFull() method or something of the sort. If an "Address" is a part of a "Person", I don't know that it is conceptually wrong for the PersonDAO object to also know how to populate Person instance with Address records. And making PersonDAO call AddressDAO to do the actual data access would seem to provide good separation of concerns (each DAO accesses it's own table and delegates to other DAOs where it needs to get more data to return more complex results).
As #Thieson alludes to, you have to ask yourself why you are bothering to derive. If there is functionality that you really do want to inherit and reuse between them, then fine. But otherwise there may be no point. I've seen a number of systems with a large quantity of objects where there is no direct hierarchy between the various DAO objects (broadleaf for example).
You'll probably get several answers here telling you to simply do whatever makes the most sense, and that's definitely good advice.
You don't have to necessarily follow your entity relationship schema on your DAOs.
You can simply add a method called listAllWithAddress, for example, in the PersonDAO or create a separated DAO called PersonAddressDAO to represent their relationship.
There are no rules regarding that, but your own sense of judgement.
Regardless your comment about not adding the method, i would add the method in the PersonDAO, because it is going to return to me Person entities anyway, even if the addresses are populated.
My advice to you is to worry more about making sense then following restrictive rules
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.
In our code base we make extensive use of DAOs. In essence a layer that exposes a low level read/write api and where each DAO maps to a table in the database.
My question is should the dao's update methods take entity id's or entity references as arguments if we have different kinds of updates on an entity.
For example, say we have customers and adressess. We could have
customer.address = newAddress;
customerDao.updateCustomerAddress(customer);
or we could have
customerDao.updateCustomerAddress(customer.getId(), newAddress);
Which approach would you say is better?
The latter is more convenient since if we have the entity we always have the id, so it will always work. The converse is not always the case though, but would have to be preceded with getting the entity before performing the update.
In DDD we have Aggregates and Repositories. Aggregates ensure that the business invariants hold and Repositories handle the persistence.
I recommend that Aggregates should be pure, with no dependencies to any infrastructure code; that is, Aggregates should not know anything about persistence.
Also, you should use the Ubiquitous language in your domain code. That being said, your code should look like this (in the application layer):
customer = customerRepository.loadById(customerId);
customer.changeAddress(address);
customerRepository.save(customer);
I assume your question is
Which approach of the two is better?
I would prefer the second approach. It states clearly what will be done. The update object will be freshly loaded and it is absolutely clear that only the address will be updated. The first approach leaves room for doubt. What happens if customer.name has a new value aswell? Will it also be update?
Can someone please explain the best way to solve this problem.
Suppose I have three classes
1.Person
2.Venue
3.Vehicle
I have a DAO method that needs to return some or all of these attributes from each of the classes after doing a query.
How do I accomplish this ? It seems very wrong to make a class PersonVenueVehicle and return that as an object to get the instance field, values.
I was taught that the database entities must be reflected by classes, if this is case how is it implemented in such a situation
Try the Spring-ish solution. Besides your three classes, you can have 3 DAO classes, one for each. But you have a task to perform; I don't know what it is; I'm just going to guess.
Suppose you are running a taxi service; Persons schedule through your company taxis to pick them up at a Venue, and you send them a Vehicle. Call this combination a Trip, and now you want a class that manages Trips in the database. Create a class called TripService. This should use your PersonDao, your VenueDao, and your VehicleDao to create if necessary person and venue records in the database, and should do the calculations needed to choose which Vehicle to use. When it does, it should use a new TripDao to persist a new Trip object. But, as the organizer, it should create and vend the database connection to all the DAOs, and should do the commit or rollback itself.
If you're using Hibernate or JPA, your classes could be modified. But the principle is the same. Even if I have your motivation wrong, you can write a service that coordinates the three DAOs and vends the connection. It can, if it has to, use the connection itself to do a SELECT on the three tables JOINed together.
You lose much of the benefits of a database if the only statements you write are simple SELECTs and UPDATEs and INSERTs
With the introduction of Hibernate in my project, my code started getting really coupled, and boilerplate in many places (and it should be the other way round, right?)
I got pretty confused by a particular example. I've always considered DAO objects to be pretty generic in their nature (mostly encapsulating the basic CRUD oeprations as well as the backend storage implementation)
Unfortunately, as my entity classes started to get more complicated, I started offloading more and more logic to the DAO objects. I have a particular example:
my entity class User should have a relation called friends, which is essentially a collection of users. However, I have to map my class to a collection of UserFriendship objects instead, each of which contains a ref to the friend object, but also other specific friendship data (the date when the friendship occurred)
Now, it is easy to introduce a custom getter in the entity class, which will take the collection of UserFriendship objects and turn it into a collection of User objects instead. However, what if I need only a subset of my friends collection, say, like in paging. I cannot really do that in the entity object, because it doesn't have access to the session, right? This also applies to when I need to make a parametrized query on the relationship. The one that has the access to the session is the UserDAO. So I ended up with this
UserDAO
=> normal CRUD methods
=> getFriends(Integer offset, Integer limit);
=> a bunch of similar getters and setters responsible for managing the relationships within the User instance.
This is insane. But I cannot really do anything else. I am not aware if it is possible to declare computed properties within the entity classes, which could also be parametrized.
I could technically also wrap the DAO within the entity, and put the helper getters and setters back into the entity class, where they should be, but I am not sure whether if that is a good practice as well.
I know that the DAO should only be accessed by the controller object, and it should provide a more or less complete entity object or a set of entity objects.
I am deeply confused. More or less all of my DAO objects now couple logic that should be either in the Entity objects or in the controllers.
I am sorry if my question is a bit confusing. It is a bit hard to formulate it.
My general rules are:
in the entity classes, respect the law of Demeter: don't talk to strangers
the entity classes must not use the session
the controller/service classes must not use the session. They may navigate in the graph of entities and call DAO methods
DAO methods should be the ones using the session. Their work consists in getting, saving, merging entities and executing queries. If several queries or persistence-related actions should be executed for a single use-case, the controller/service should coordinate them, not the DAO.
This way, I can test the business logic relatively easily by mocking the DAOs, and I can test the DAOs relatively easily because they don't contain much logic. Most of the tests verify that the queries find what they're supposed to find, return them in the appropriate order, and initialize the associations that must be initialized (to avoid lazy loading exceptions in the presentation layer, where I'm using detached objects)
I'm using EJB 3.1 and JPA 2.0.
I'll give you an example to explain my doubts and ask for hints as what is a good practice and what's not.
Let's say I have an EJB that's a user Facade. So you have something like this:
#Stateless
public class UserRepository {
public User find(Long id) {
...do user lookup using entitymanager.
}
}
Alright, now let's say I return the User entity from this and that this entity has a collection of comments (Comment being also an entity).
I could have a Comment Repository with a findCommentsByUser(Long userId) method, or I could fetch the user and call the getComments() method. May be this case is simple, but I've faced this decision many times sometimes not knowing what is best.
Also, let's say I want to add a comment, should I add it to the comment collection the entity has and the have the entity merged, or should I have a addComment(Long userId, Comment newComment) method?
I'm looking for advice or best practices regarding this. If you need further clarifications please do not hesitate to ask.
EDIT:
I've found the comments so far helpful, however notice this, it isn't really about users and comments, I just made that up to explain my situation. It's about whether it is convenient to mix both approaches (which I think is not) or is one better over the other. I liked the "always persist through the repositories" suggestion. But the fact that I have a fetchComments() repository method and the getComments() in the user entity creates to entry points for the same functionality, so how do I deal with that?.
Also the performance (1 query vs 2 queries) isn't really important because I will be fetching the user entity too so it's not like I'm actually saving anything.
We typically only work with detached entities in our applications, so we have a data access manager to fetch and update entities. Then we know that anything we do in our business logic will not be persisted unless specifically called to. I would also fetch the comments with the user entity, but make sure it is not persisted until explicitly called.
I could have a Comment Repository with a findCommentsByUser(Long
userId) method, or I could fetch the user and call the getComments()
I would say that from a performance point of view, the first alternative is slightly better, because you don't fech the user (1 query) and then the comments (another query). The first does it in a single shot.
In the other side, i find the second more readable, abstract, and object oriented approach. I would use this one.
You would generally add the getComments() method to your user object. When you want to add one, you would add it to the user set and then call update on the user object.
I think this highly depends on the requirements, on how fine-grained control of the process do you want to have (this often depends on the performance requirements and expected load, etc.).
If the comments are never to be retrieved independently, I would only keep them as a reference inside User.
If you, however, want to get the comments regardless of the user, or you want to perform some other comments-related queries (like all the comments for users in group A), then I would create separate CommentsRepository.
If you want to be able to add the comment to a user that's not loaded from the DB, but you have the foreign key, you may simply want to add the comment through CommentsRepository like you suggested (also adding a comment to a list of user's comments in parallel and persisting such two lists into DBs may result in 'weird behavior').
There are several considerations that needs to make I hope I will document them here for you.
Domain model is important consideration in EJB3. In your example if you see your domain model allows you to fetch comments lazily because in any flow you show user details first and then his comments.
In some cases your collection (I am referring to comments here) may contain lots of data, In this case its hardly question of string data so not a major concern, but if it would have been real application data then always opt for transient relationship and provide appropriate methods to fetch them independently.
Its never a good practice to expose your collection inside entity bean to outside world so if you OneToMany or ManyToMany relationship then you should provide three basic methods over collections (add, remove, get).
Collections.unmodifiableCollection method should be used while returning collections from get method.
Always use Set when you are using collections inside entities remember they do not allow duplicate.
In your case comments collection has direct dependency on user so you should use cascade type in user to save comments.
I am not convinced why you need UserRepository because em.find method will do job for you.
By default for OneToMany relation fetchtype is lazy so if you want to do eager load you will need to specify it.
I hope these guidelines hopes to solve your problem.
Regards,
Amit