Best Practice with a service using hibernate
I'm using Hibernate and I have a process/best practices issue. For an example, lets assume we have 2 entities Truck and Wheel. The wheel has 2 properties wheelid and wheelmanufacturer. So in my application, the user can create a truck, they can select various wheels that exists in the database or create their own wheel.
My question is when I receive a truck object from the front-end , how do I make sure that if the wheel does exist in the database, the db copy is used and if it doesn't exist in the database, it is added. Here is a rudimentary example of how my services work now
public Truck saveTruck( Truck truck )
{
//Yes, this is a two-wheel truck =)
Wheel frontWheel = truck.getFrontWheel();
if( frontWheel != null && frontWheel.getWheelId() != null )
{
Wheel dbWheel = wheelDao.getWheelById( frontWheel.getWheelId() );
if( dbWheel != null )
{
truck.setFrontWheel(dbWheel );
}
}
}
The motivation for this is that I don't want users to be able to overwrite objects in the databa开发者_如何学Pythonse, however they need to be able to write custom ones. The above code works, but it becomes very redundant if you have a truck with say 10 properties. I was wondering how others solve this problem.
Thanks
That's exactly what the merge()
operation do.
That is, your code can be replaced by the following:
public Truck saveTruck( Truck truck ) {
//Yes, this is a two-wheel truck =)
Wheel frontWheel = truck.getFrontWheel();
if( frontWheel != null) {
truck.setFrontWheel(wheelDao.merge(dbWheel));
}
}
where wheelDao.merge()
provides access to Session.merge()
.
If your Truck
has many properties to be merged, you can configure them to cascade a merge()
operation and merge the Truck
as a whole:
public Truck saveTruck( Truck truck ) {
return session.merge(truck);
}
See also:
- 11.7. Automatic state detection
- 11.11. Transitive persistence
I solve these kind of problems at user interface part of the application. I have a component to display value objects such as wheel, if the user could not find the requested wheel from existing wheels, the user can create a new wheel by means of the component.
I would implement this by seperating the GUI from the Backend.
The GUI would use a TruckDTO which is almost the Truck object, but instead of a Weel it contains a WeelManufactuer String.
The GUI Controller recive the TruckDTO and forward it to some Service. The service, seach for a Weel with the manufactuer in the DB. If there is no such weel it creates it. Then it uses the weel (new or existing one) and the TruckDTO to create the Truck Object.
The same is for updating the Truck. (Of course, instead of create a new Truck, you have to change it).
I put the logic to handle that not in the interface part, but in the service part of the application. Because so no GUI implementation can forget to implement the correct handling.
精彩评论