title: Converting DAO objects to DTO objects in a Spring MVC Application
body: <p><strong>Background:</strong> I work in an education environment and last summer one of our developers designed and built a Java web application using Spring MVC and Hibernate. It launched with the new term in September to much joy from the users as it replaced a dusty old Blackboard plugin. The primary functions of the applications are used for setting targets for a student, leaving them messages and creating reports for students.</p>
  
  <p>Fast forward a few months, the original developer has moved on and the application is having some growing pains.</p>
  
  <p><strong>Use Case Scenario:</strong> A Teacher logs in and they are presented with their home screen which contains a list of courses which they teach on, with an overview of Targets, messages and Reports for the currently selected course as well as a list of student enrolments for the course. If a course contains a small number of targets etc then it's quick to return the information. But as the amount of information grows, the time taken to load it seems to increase exponentially. </p>
  
  <p>After investigating I think I've found out why. I took a sample course and took a look at Reports to see what was going on. and I found that the Database returned the relevant data in milliseconds, the browser rendered it in milliseconds but there was 12 seconds in between when the browser was waiting for data to be returned from it. The only thing that gets done to the objects between the database query finishing and the front end receiving the response is a convert to DTO.</p>
  
  <p><strong>Code:</strong> This is what the Report Object looks like in the DAO layer</p>
  
  <pre><code>@Entity
  @Table(name = "REPORTS")
  public class Report implements Serializable
  {
  
      /**
       * 
       */
      private static final long   serialVersionUID    = -7659637777880535914L;
  
      @Id
      @GeneratedValue
      @Column(name = "REPORT_ID", insertable = true, updatable = false, nullable = false, unique=true)
      private Integer             reportID;
  
      @Column(name = "DATE_CREATED", insertable = true, updatable = false, nullable = false)
      private GregorianCalendar   dateCreated;
  
      @Column(name = "DATE_MODIFIED", insertable = true, updatable = true, nullable = true)
      private GregorianCalendar   dateModified;
  
      @Column(name = "TITLE", insertable = true, updatable = true, nullable = false, length=1000)
      private String              title;
  
      @Column(name = "CURRENT_PERFORMANCE_GRADE", insertable = true, updatable = true, nullable = false)
      private String              currentPerformanceGrade;
  
      @Column(name = "TARGET_GRADE", insertable = true, updatable = true, nullable = false)
      private String              targetGrade;
  
      //VARCHAR(MAX) as this is the main body of the tutor report comments. Here the tutor can write as much content as they like.
      @Column(name = "TUTOR_COMMENTS", insertable = true, updatable = true, nullable = false, columnDefinition="VARCHAR(MAX)")
      private String              tutorComments;
  //getters and setters below
  }
  </code></pre>
  
  <p>There are other fields in there too like the user the report is linked to, the course, the tutor who wrote it etc. but I left them out for simplicity's sake here.</p>
  
  <pre><code>public class ReportDTO implements Serializable
  {
  
  /**
   * 
   */
  private static final long   serialVersionUID    = 2795129355073929139L;
  
  private Integer             reportID;
  
  private String              dateCreated;
  
  private String              dateModified;
  
  private String              title;
  
  private String              currentPerformanceGrade;
  
  private String              targetGrade;
  
  private String              tutorComments;
  //getters and setters below
  }
  </code></pre>
  
  <p>So the main differences are with the date objects have become date formatted strings as opposed to GregorianCalendar objects so that the front end display of the date is in a nice readable format. Here's an example of what the converting to DTO involves. A Single method in the service layer which takes the DAO object, gets the relevant fields from it, sets them in the newly constructed DTO object, converts as needed (e.g. Gregorian Calendar to date formatted String) and returns the DTO:</p>
  
  <pre><code>public ReportDTO convertToDto(Report daoReport) throws Exception
  {
  
      ReportDTO dtoReport = new ReportDTO();
      try
      {
                      if(daoReport.getReportID() != null)
          {
              dtoReport.setReportID(daoReport.getReportID());
          }
                      if(daoReport.getDateCreated() != null)
          {
              dtoReport.setDateCreated(ReportServiceImpl.ISO_DATE_TIME_FORMAT.format(daoReport.getDateCreated().getTime()));
  
          }
  
          if(daoReport.getDateModified() != null)
          {
               dtoReport.setDateModified(ReportServiceImpl.ISO_DATE_TIME_FORMAT.format(daoReport.getDateModified().getTime()));
  
          }
  
          if(daoReport.getTitle() != null)
          {
              dtoReport.setTitle(daoReport.getTitle());
  
          }
                       if(daoReport.getCurrentPerformanceGrade() != null)
          {
                dtoReport.setCurrentPerformanceGrade(daoReport.getCurrentPerformanceGrade());
  
          }
  
          if(daoReport.getTargetGrade() != null)
          {
              dtoReport.setTargetGrade(daoReport.getTargetGrade());
  
          }
  
          if(daoReport.getTutorComments() != null)
          {
              dtoReport.setTutorComments(daoReport.getTutorComments());
  
          }
                      return dtoReport;
      }
      catch(Exception e)
      {
          Exception myException = new Exception("Exception was thrown while converting a persistent Report object to it's data transport equivalent", e);
          throw myException;
      }
  </code></pre>
  
  <p><strong>Question:</strong> So after all that, my question is, is this the correct way of converting from DAO to DTO? Since he left I had been following his code and anything new added was done in the same way. Returning the Objects to the front end without converting them I see the results in >300 milliseconds instead of 12 seconds.</p>
  
  <p>I know he learned Spring MVC from <a href="http://krams915.blogspot.co.uk/p/tutorials.html" rel="nofollow">here</a> for the project so he wasn't an experienced Spring Developer and neither am I and judging by the fact we're seeing such large request times we must be doing something wrong.</p>