I have an entity that needs to be slightly modified before it is returned to the user. From what I understand, the best way to do that is to use a Data Transfer Object.
That is working fine, but then I added a child entity. I again created a DTO for the child entity. Here is the code for the repository:
@Repository
public interface DrawingReleaseRepository extends CrudRepository<DrawingRelease, Integer> {
@Query("SELECT new com.engineering.dto.drawings.DrawingReleaseDTO("
+ "dwgrel.drawingReleaseID,"
+ "relType"
+ ") FROM DrawingRelease dwgrel "
+ "JOIN dwgrel.releaseType relType "
+ "WHERE dwgrel.drawingReleaseID = ?1")
DrawingReleaseDTO getDrawingRelease(int drawingReleaseID);
}
The constructor for DrawingReleaseDTO is this:
public DrawingReleaseDTO(int drawingReleaseID, DrawingReleaseType releaseType) {
this.drawingReleaseID = drawingReleaseID;
this.releaseType = new DrawingReleaseTypeDTO(releaseType);
}
In my service layer, I can now manipulate the data and have that returned to the client, but the changes are not persisted to the database (which is what I want):
@Override
public DrawingReleaseDTO findByID(int id) {
DrawingReleaseDTO dto = repository.getDrawingRelease(id);
dto.getReleaseType().setCustom1(true);
return dto;
}
The problem with that scenario is that it is not very efficient. What I mean is that Hibernate executes two queries - one for the DrawingRelease
and one for the DrawingReleaseType
.
I thought that the way to fix this would be to specify JOIN FETCH dwgrel.releaseType relType
, as that should force hibernate to fetch all the data in one shot, but that produces the error:
query specified join fetching, but the owner of the fetched association was not present in the select list
Is there a way to use a DTO, include data for child entities, AND have it all use efficient queries?