I am evaluating Hibernate to see if we can use it instead of our current ORM tool. One feature we use today that I haven't so far been able to get to work in Hibernate is to read DTOs directly from the database instead of reading entities and then copying data to the DTOs.
I know there has been a lot of discussion on whether to use DTOs or not but skipping the DTOs is not an option for me for legacy reasons.
The DTOs are similar to the entity classes but lack some properties which are only kept in the domain layer.
Example:
There is an entity Car which has a one-to-many association to entity Seat.
These are mapped to one table each, eg Car_Tb and Seat_Tb respectively.
Besides the classes Car and Seat which only exist in the domain layer I need two DTOs: CarTO and SeatTO.
CarTO and SeatTO are mapped to the same tables as Car and Seat, but only the properties needed in the DTOs are mapped.
When loading a DTO I immediately evict it to avoid any flushing:
Code between sessionFactory.openSession() and session.close():
Code:
Session session = sessionFactory.openSession();
CarTO dto = (CarTO) session.get(CarTO.class, id);
session.evict(dto);
session.close();
return dto;
This works fine besides the collections. The DTOs use Hibernates own collection implementations which make the DTOs unusable in layers that don't know about Hibernate, such as desktop clients.
I have tried to use a PropertyAccessor to replace the collection implementations with the ones from java.util, ie HashSet and ArrayList, but then the evict will not work properly as it seems to rely on Hibernates collection implementations.
What I need is a Session.get() method that automatically evicts the entities and therefore don't need to use special collection implementations.
Any hints on how this can be done?
Peter
Hibernate version: 2.1.4
Mapping documents:
<class name="Car" table="Car_Tb">
<id name="Id" column="CAR_ID" type="int">
<generator class="assigned" />
</id>
<version name="UpdateId" column="Update_Id" type="long" />
<property name="Name" type="string" />
<property name="Type" type="long" column="Type" />
<property name="CreatedWhen" type="timestamp" column="Created_When"/>
<property name="CreatedBy" type="long" column="Created_By" />
<property name="UpdatedBy" type="long" column="Updated_By" />
<property name="UpdatedWhen" type="timestamp" column="Updated_When" />
<set name="Seats" cascade="all-delete-orphan" >
<key column="CAR_FK" />
<one-to-many class="Seat" />
</set>
</class>
<class name="Seat" table="Seat_Tb">
<id name="Id" column="SEA_ID" type="int">
<generator class="assigned" />
</id>
<version name="UpdateId" column="Update_Id" type="long" />
<property name="Color" type="string" />
<property name="Size" type="string" />
<property name="CreatedBy" type="long" column="Created_By" />
<property name="CreatedWhen" type="timestamp" column="Created_When"/>
<property name="UpdatedBy" type="long" column="Updated_By" />
<property name="UpdatedWhen" type="timestamp" column="Updated_When" />
</class>
<class name="CarTO" table="Car_Tb">
<id name="Id" column="CAR_ID" type="int">
<generator class="assigned" />
</id>
<version name="UpdateId" column="Update_Id" type="long" />
<property name="Name" type="string" />
<property name="Type" type="long" column="Type" />
<set name="Seats" cascade="all-delete-orphan">
<key column="CAR_FK" />
<one-to-many class="SeatTO" />
</set>
</class>
<class name="SeatTO" table="Seat_Tb">
<id name="Id" column="SEA_ID" type="int">
<generator class="assigned" />
</id>
<version name="UpdateId" column="Update_Id" type="long" />
<property name="Color" type="string" />
<property name="Size" type="string" />
</class>