Uploaded image for project: 'Jira Data Center'
  1. Jira Data Center
  2. JRASERVER-36334

Updated Date is not set correctly when setting tweakIssueUpdateDate to true

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Low
    • 6.2
    • 4.0, 6.1.5
    • Java API

    Description

      Problem:

      Since JIRA 4.0 (after implementing JRA-15723), JIRA does not set the Updated Date correctly on issues when being called using:

      public Comment create(Issue issue, ApplicationUser author, ApplicationUser updateAuthor, String body, String groupLevel, Long roleLevelId, Date created, Date updated, boolean dispatchEvent, boolean tweakIssueUpdateDate)
      

      CommentManager.java - Java docs

      CommentManager.java
        /**
           * Creates a comment and associates it with the given issue. Using this method the comment will be created
           * with a createdDate of the specified date. This method should be used if you are trying to preserve existing
           * information and it is important to retain the original created date. If you have provided a groupLevel then the
           * comment visibility will be restricted to the provided group, it is assumed that validation to ensure that the
           * group actually exists has been performed outside of this method. If you have provided a roleLevelId then the
           * comment visibility will be restricted to the provided role, it is assumed that validation to ensure that the
           * role actually exists has been performed outside of this method.
           * <p/>
           * <strong>NOTE:</strong> A comment should not have both a group level and role level visibility restriction. This
           * method will not stop this, but it does not semantically make sense.
           *
           * @param issue                the issue to associate the comment with.
           * @param author               the key of the user who has created this comment.
           * @param updateAuthor         the key of the user who has updated this comment last
           * @param body                 the text of the comment.
           * @param groupLevel           is the group name to limit comment visibility to, this must be a valid group name.
           * @param roleLevelId          is the id of the the {@link ProjectRole} to limit comment visibility to, this must reference a
           *                             valid project role.
           * @param created              is the date that will be used as the comments creation date.
           * @param updated              is the date that will be used as the comments updated date.
           * @param dispatchEvent        if true then an event of type {@link com.atlassian.jira.event.type.EventType#ISSUE_COMMENTED_ID}
           *                             will be dispatched and any notifications listening for that event will be triggered.
           *                             If false no event will be dispatched.
           * @param tweakIssueUpdateDate if true the issues 'updated' date will be set to now.
           * @return the object representation of the newly created comment.
           */
          public Comment create(Issue issue, ApplicationUser author, ApplicationUser updateAuthor, String body, String groupLevel, Long roleLevelId, Date created, Date updated, boolean dispatchEvent, boolean tweakIssueUpdateDate);
      

      tweakIssueUpdateDate if true the issues 'updated' date will be set to now.

      Judging by the above, setting the last boolean to true would make JIRA use the current date/time as the update date for the issue. However, in the DefaultCommentManager.java:

      DefaultCommentManager.java
          /**
           * @see com.atlassian.jira.issue.comments.CommentManager#create(com.atlassian.jira.issue.Issue,ApplicationUser,ApplicationUser,String,String,Long,java.util.Date,java.util.Date,boolean,boolean)
           */
          @Override
          public Comment create(Issue issue, ApplicationUser author, ApplicationUser updateAuthor, String body, String groupLevel, Long roleLevelId, Date created, Date updated, boolean dispatchEvent, boolean tweakIssueUpdateDate)
                  throws DataAccessException
          {
              if (textFieldCharacterLengthValidator.isTextTooLong(body))
              {
                  final long maximumNumberOfCharacters = textFieldCharacterLengthValidator.getMaximumNumberOfCharacters();
                  String errorMessage = getText("field.error.text.toolong", String.valueOf(maximumNumberOfCharacters));
                  throw new IllegalArgumentException(errorMessage);
              }
      
              // create new instance of comment
              CommentImpl comment = new CommentImpl(this, author, updateAuthor, body, groupLevel, roleLevelId, created, updated, issue);
      
              // create persistable generic value
              Map<String, Object> fields = new HashMap<String, Object>();
              fields.put("issue", issue.getId());
              fields.put("type", ActionConstants.TYPE_COMMENT);
      
              ApplicationUser commentAuthor = comment.getAuthorApplicationUser();
              ApplicationUser commentUpdateAuthor = comment.getUpdateAuthorApplicationUser();
              fields.put("author", commentAuthor == null ? null : commentAuthor.getKey());
              fields.put("updateauthor", commentUpdateAuthor == null ? null : commentUpdateAuthor.getKey());
              fields.put("body", comment.getBody());
              fields.put("level", comment.getGroupLevel());
              fields.put("rolelevel", comment.getRoleLevelId());
              fields.put("created", new Timestamp(comment.getCreated().getTime()));
              fields.put("updated", new Timestamp(comment.getUpdated().getTime()));
      
              GenericValue commentGV = EntityUtils.createValue(COMMENT_ENTITY, fields);
              // set the ID on comment object
              comment.setId(commentGV.getLong(COMMENT_ID));
      
              // Update the issue object if require
              if (tweakIssueUpdateDate)
              {
                  IssueFactory issueFactory = ComponentAccessor.getComponentOfType(IssueFactory.class);
                  MutableIssue mutableIssue = issueFactory.getIssue(issue.getGenericValue());
                  //JRA-15723: Use the comments updated time for the updated time of the issue.  This allows users to
                  // import old comments (via Jelly for example) without setting the updated time on the issue to now, but to the date
                  // of the old comments.
                  mutableIssue.setUpdated(new Timestamp(comment.getUpdated().getTime()));
                  issue.store();
              }
      
              // Dispatch an event if required
              if (dispatchEvent)
              {
                  dispatchEvent(EventType.ISSUE_COMMENTED_ID, comment, EasyMap.build("eventsource", IssueEventSource.ACTION));
              }
              return comment;
          }
      

      More Specifically:

      public Comment create(Issue issue, ApplicationUser author, ApplicationUser updateAuthor, String body, String groupLevel, Long roleLevelId, Date created, Date updated, boolean dispatchEvent, boolean tweakIssueUpdateDate)
              if (tweakIssueUpdateDate)
              {
                  IssueFactory issueFactory = ComponentAccessor.getComponentOfType(IssueFactory.class);
                  MutableIssue mutableIssue = issueFactory.getIssue(issue.getGenericValue());
                  //JRA-15723: Use the comments updated time for the updated time of the issue.  This allows users to
                  // import old comments (via Jelly for example) without setting the updated time on the issue to now, but to the date
                  // of the old comments.
                  mutableIssue.setUpdated(new Timestamp(comment.getUpdated().getTime()));
                  issue.store();
              }
      

      Which seems to state that, if true, JIRA gets the date from the comment that is being added and makes it the update date for the issue.

      Conclusion:

      On CommentManager.java, it is stated that setting tweakIssueUpdateDate to true would make JIRA use the current date/time as the update date for the issue. However, on DefaultCommentManager.java it seems that , if tweakIssueUpdateDate is true, JIRA gets the date from the comment that is being added and makes it the update date for the issue instead.

      Proposed Solution:

      Change the following part:

      public Comment create(Issue issue, ApplicationUser author, ApplicationUser updateAuthor, String body, String groupLevel, Long roleLevelId, Date created, Date updated, boolean dispatchEvent, boolean tweakIssueUpdateDate)
              if (tweakIssueUpdateDate)
              {
                  IssueFactory issueFactory = ComponentAccessor.getComponentOfType(IssueFactory.class);
                  MutableIssue mutableIssue = issueFactory.getIssue(issue.getGenericValue());
                  //JRA-15723: Use the comments updated time for the updated time of the issue.  This allows users to
                  // import old comments (via Jelly for example) without setting the updated time on the issue to now, but to the date
                  // of the old comments.
                  mutableIssue.setUpdated(new Timestamp(comment.getUpdated().getTime()));
                  issue.store();
              }
      

      to

      public Comment create(Issue issue, ApplicationUser author, ApplicationUser updateAuthor, String body, String groupLevel, Long roleLevelId, Date created, Date updated, boolean dispatchEvent, boolean tweakIssueUpdateDate)
              if (!tweakIssueUpdateDate)
              {
                  IssueFactory issueFactory = ComponentAccessor.getComponentOfType(IssueFactory.class);
                  MutableIssue mutableIssue = issueFactory.getIssue(issue.getGenericValue());
                  //JRA-15723: Use the comments updated time for the updated time of the issue.  This allows users to
                  // import old comments (via Jelly for example) without setting the updated time on the issue to now, but to the date
                  // of the old comments.
                  mutableIssue.setUpdated(new Timestamp(comment.getUpdated().getTime()));
                  issue.store();
              }
      

      Workaround:

      Instead of setting 'true' when calling the constructor, set false instead so it doesn't enter the loop.

      Attachments

        Issue Links

          Activity

            People

              mlassau Mark Lassau (Inactive)
              mfernandes@atlassian.com Matheus Fernandes
              Votes:
              1 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: