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
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 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
I am working on a stand-alone Java project (not Java EE), I am currently learning JDBC, I am creating a database where it contains Employee information, such as Personal information, Contact Information, Employee Information and Tax information, all of these are classes with references with each other and they have setters and getters, I am wondering how would I insert their data value in the database/tables I created in the database? in short I have Employee an employee object with like this
Employee(PersonalInformation information,ContactInformation cInformation)
Something like that, how would I add their data in the tables I made in the database?
how would I add their data in the tables I made in the database?
By using JDBC to send INSERT statements to the database, one for each object in your object graph (assuming you have one table per class).
And yes, that's a lot of boring, repetitive code to write, which is likely to contain errors and quite a burden to maintain.
Which is why people have written Object-Relational mappers like Hibernate, and there's a Java standard for that called JPA. Which is part of Java EE, but that doesn't mean you have to run a Java EE server to use it.
Update: OK, so you cannot use an ORM, probably because you're supposed to understand how JDBC works first, which makes sense because ORMs are based on JDBC and sometimes you have to go down to that level when there is a problem.
When using JDBC directly, you typically create a DAO (data ccess object) layer that is responsible for writing and reading objects to/from the database. For dealing with a nested object, one DAO can call the other.
And no, the DAOs are not called in the setters and getters. There called by the part of your application that reacts to user input. E.g. when the user opens the application and the start screen shows a list of employees, you'd call an EmployeeDAO.findAll() method, and when the user makes changes to an employee and clicks on "save", you'd call the EmployeeDAO.save() method.
I recommend you to look at Spring's JdbcTemplate (http://www.java2s.com/Code/Java/Spring/ControlParameterTypeInJdbcTemplateQuery.htm)
Its looks like this:
SingleConnectionDataSource ds = new SingleConnectionDataSource();
ds.setDriverClassName("org.hsqldb.jdbcDriver");
ds.setUrl("jdbc:hsqldb:data/tutorial");
ds.setUsername("sa");
ds.setPassword("");
JdbcTemplate jt = new JdbcTemplate(ds);
jt.execute("insert into employee (id, name) values (?, ?)", 1, "Tom");
Use one jdbcTemplate per DAO class instance.
This may help you
Pass all the required values to the respective objects.
get all their values and frame a query using those values like
Employee em = new Employee(perinfo, continfo);
String emp_per_info = em.getSomeInfo(); // it this returns a string
...
//so on
query="insert into table_name values(variables go here);"
let me know if it didn't work
What you are trying to do is called "Object to Relational Mapping". You have the java Objects which make up your object domain and there is the DB Table which make up the relational model. You have relate them. Save the data and query to get them back.
You have two approaches to write a kind of your own limited framework or use an existing framework. Existing frameworks include :
Hibernate
iBatis
and so on.
To do one on your own, simplest way to do would be writing simple result set to object mappers and creating insert strings.
I would suggest you study some ORM docs to know more.
Regards
The ever so popular discussion on designing proper DAOs always concludes with something along the lines of "DAOs should only perform simple CRUD operations".
So what's the best place to perform things like aggregations and such? And should DAOs return complex object graphs resembling your data source's schema?
Assume I have the following DAO interface:
public interface UserDao {
public User getByName(String name);
}
And here are the Objects it returns:
public class Transaction {
public int amount;
public Date transactionDate;
}
public class User {
public String name;
public Transaction[] transactions;
}
First of all, I consider the DAO to be returning a standard Value Object if all it does is CRUD operations.
So now I have modeled by DAO to return something based on a data store relationship. Is this correct? What if I have a more complex object graph?
Update: I guess what I am asking in this part is, should the return value of a DAO, be it VO, DTO, or whatever you want to call it, be modeled after the data store's representation of the data? Or should I, say introduce a new DAO to get a user's transactions and for each user pulled by the UserDAO, invoke a call to the TransactionDAO to get them?
Secondly, let's say I want to perform an aggregation for all of a user's transactions. Using this DAO, I can simply get a user, and in my Service loop though the transactions array and perform the aggregation myself. After all, it's perfectly reasonable to say that such an aggregation is a business rule that belong in the Service.
But what if a user's transactions number in the tens of thousands. That would have a negative impact on application performance. Would it be incorrect to introduce a new method on the DAO that does said aggregation?
Of course this might be making an assumption that the DAO is backed up by a database where I can write a simple SELECT SUM() query. And if the DAO implementation changes to say a flat file or something, I would need to do the aggregation in memory anyway.
So what's the best practice here?
I use the DAO as the translation layer: read the db objects, create the java side business objects and vice versa. Sometimes a couple of calls might be used to store or create a business object. For the provided example, I would make two calls: one for the user info, one for the list of the user's transactions. The cost is an extra database call. I'm not afraid to make an extra call if I'm using connection pooling and I'm not repeating calculations. Separate calls are simpler to use (unpacking an array of composite types from a jdbc call is not simple and typically requires the proprietary connection object) and provide resusable components. Let's say you wanted the user object for a login screen: you can use the same user dao and not have to pull in the transaction stuff.
If you didn't actually want the transaction details but were just interested in the aggregate, I would do the aggregate work on the database side and expose it via a view or a stored procedure. Relational databases are built for and excel at these kinds of set operations. You are unlikely to perform the operations better. Also, there is no point sending all the data over the wire if the result will do. So sure, add another dao for the aggregate if there are times you are only interested in that.
Is it safe to assume the dao maps to a relational db? If that is how you are starting, I would wager that the backing datastore will remain a relational db. Sometimes there is a lot of fuss and worry to keep it generic, and if you can, great. But it seems to me just changing the type of relational db in the back is further than most apps would go (let alone changing to a non-relational store like a flat file).
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)