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?