title: Set foreign key reference to null to clear relationship using spring boot
body: <p>I am new to spring boot application development and facing the following issue.</p>
  
  <p>I am working with an application where I am developing issues to track. Each issue can be associated to a particular category. However its not mandatory to associate an issue to a particular category.</p>
  
  <p>Issues can be created without associating them to any particular category.
  Issues can be updated to look up to an existing list of category.
  Issues can be updated to clear the linked category and keep the category as NULL.</p>
  
  <p>It is in the third case for which I am facing the following issue as reported below in the exception trail log.</p>
  
  <pre><code>2019-03-02 23:07:56.854  INFO 3984 --- [nio-8080-exec-9] c.a.m.A.controller.IssueController       : Inside updateIssue() API :: Updating Issue ::: OTPC-1000
  2019-03-02 23:07:56.855  INFO 3984 --- [nio-8080-exec-9] c.a.m.A.controller.IssueController       : updateIssue() :: Logging input parameters passed for updated!
  2019-03-02 23:07:56.856  INFO 3984 --- [nio-8080-exec-9] c.a.m.A.controller.IssueController       :  Key ::: (component) ==&gt; value ::: ()
  2019-03-02 23:07:56.856  INFO 3984 --- [nio-8080-exec-9] c.a.m.A.controller.IssueController       :  Key ::: (id) ==&gt; value ::: (OTPC-1000)
  2019-03-02 23:07:56.859  INFO 3984 --- [nio-8080-exec-9] c.a.m.A.services.IssueServiceImpl        :  Inside updateIssuebyIssueId() API in IssueServiceImpl ::: OTPC-1000
  2019-03-02 23:07:56.860  INFO 3984 --- [nio-8080-exec-9] c.a.m.A.services.IssueServiceImpl        : updateIssuebyIssueId() :: Update Query :: update issue i set i.component = ?, i.id = ? where i.id = ?
  2019-03-02 23:07:56.868  INFO 3984 --- [nio-8080-exec-9] c.a.m.A.services.IssueServiceImpl        : updateIssuebyIssueId() :: Final Update Query with values :: update issue i set i.component = ?, i.id = ? where i.id = ?
  Hibernate:
      update
          issue i
      set
          i.component = ?,
          i.id = ?
      where
          i.id = ?
  2019-03-02 23:07:56.894  WARN 3984 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1452, SQLState: 23000
  2019-03-02 23:07:56.894 ERROR 3984 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper   : Cannot add or update a child row: a foreign key constraint fails (`agilecenterdb`.`issue`, CONSTRAINT `FKnwf3mlopxg840otjaqxjidwbf` FOREIGN KEY (`component`) REFERENCES `issue_component` (`id`))
  Exception encountered
  javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
          at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
          at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
          at org.hibernate.jpa.spi.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1700)
          at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:70)
          at com.app.mycompany.AgileCenterServices.services.IssueServiceImpl.updateIssuebyIssueId(IssueServiceImpl.java:194)
  </code></pre>
  
  <p>I have defined the entities in the following way</p>
  
  <p><strong>Issue.java</strong></p>
  
  <pre><code>import java.util.Date;
  
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.EntityListeners;
  import javax.persistence.GeneratedValue;
  import javax.persistence.Id;
  import javax.persistence.JoinColumn;
  import javax.persistence.ManyToOne;
  import javax.persistence.Table;
  
  import org.hibernate.annotations.GenericGenerator;
  import org.hibernate.annotations.Parameter;
  import org.springframework.context.annotation.Scope;
  import org.springframework.data.jpa.domain.support.AuditingEntityListener;
  
  import com.app.mycompany.AgileCenterServices.audit.Auditable;
  
  @Entity
  @Table(name="Issue")
  @EntityListeners(AuditingEntityListener.class)
  @Scope("session")
  public class Issue extends Auditable&lt;String&gt; {
  
      @Id
      @GenericGenerator(name = "sequence_issue_id", strategy = "com.app.mycompany.AgileCenterServices.util.IssueIdGenerator",
                        parameters = @Parameter(name = "ProjectKey", value = "PeopleCenter" ))
      @GeneratedValue(generator = "sequence_issue_id")
      @Column(unique = true)
      private String id;
  
      private String issueType;
  
      private String summary;
  
      @ManyToOne
      @JoinColumn (nullable = true, updatable = true, name = "component", referencedColumnName = "id")
      private IssueComponent component;
  
      /* getters and setters */
  }
  </code></pre>
  
  <p><strong>IssueComponent.java</strong></p>
  
  <pre><code>import java.util.Set;
  
  import javax.persistence.CascadeType;
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.EntityListeners;
  import javax.persistence.GeneratedValue;
  import javax.persistence.Id;
  import javax.persistence.JoinColumn;
  import javax.persistence.ManyToOne;
  import javax.persistence.OneToMany;
  import javax.persistence.PreRemove;
  import javax.persistence.Table;
  
  import org.hibernate.annotations.GenericGenerator;
  import org.springframework.context.annotation.Scope;
  import org.springframework.data.jpa.domain.support.AuditingEntityListener;
  
  import com.app.mycompany.AgileCenterServices.audit.Auditable;
  import com.fasterxml.jackson.annotation.JsonBackReference;
  
  @Entity
  @Table(name="IssueComponent")
  @EntityListeners(AuditingEntityListener.class)
  @Scope("session")
  public class IssueComponent extends Auditable&lt;String&gt; {
  
      @Id
      @GenericGenerator(name = "sequence_issuecomponent_id", strategy = "com.app.mycompany.AgileCenterServices.util.IssueComponentIdGenerator")
      @GeneratedValue(generator = "sequence_issuecomponent_id")
      @Column(unique = true)
      private String id;
  
      private String name;
  
      private String description;
  
      private Integer totalIssues;
  
      @ManyToOne
      @JoinColumn (name = "componentLead", referencedColumnName = "username")
      private User componentLead;
  
      @ManyToOne
      @JoinColumn (name = "project", referencedColumnName = "id")
      private Project project;
  
      @Column(nullable = false, name = "active", columnDefinition = "BOOLEAN")
      private Boolean active;
  
      @JsonBackReference
      @OneToMany(mappedBy="component", cascade = CascadeType.PERSIST)
      private Set&lt;Issue&gt; issues;
  
      /* getters &amp; setters */
  }
  </code></pre>
  
  <p><strong>IssueServiceImpl.java</strong></p>
  
  <pre><code>@Override
      @Transactional
      public int updateIssuebyIssueId(String issueId, Map&lt;String, String&gt; customUpdateQuery)
              throws NoResultException, Exception {
  
          logger.info(" Inside updateIssuebyIssueId() API in IssueServiceImpl ::: " + issueId);
  
          int columnsToUpdate = 0;
  
          StringBuilder updateSqlQuery = new StringBuilder("update issue i set ");
  
          for(String key : customUpdateQuery.keySet()) {
  
              if(key != null &amp;&amp; (key.equalsIgnoreCase("createdBy")) 
                      || (key.equalsIgnoreCase("modifiedBy"))) {
                  continue;
              }
  
              String column = key;
  
              if(key != null &amp;&amp; key.equalsIgnoreCase("status")) {
      //          issueStatusUpdated = true;
              }
  
              if(key != null &amp;&amp; key.equalsIgnoreCase("epicStatus")) {
                  column = "epic_status";
              }
  
              if(key != null &amp;&amp; key.equalsIgnoreCase("issueType")) {
                  column = "issue_type";
              }
  
              if(key != null &amp;&amp; key.equalsIgnoreCase("dueDate")) {
                  column = "due_date";
              }
  
              if(key != null &amp;&amp; key.equalsIgnoreCase("startDate")) {
                  column = "start_date";
              }
  
              if(key != null &amp;&amp; key.equalsIgnoreCase("assignedToUser")) {
                  column = "assigned_to_user";
              }
  
              if(key != null &amp;&amp; key.equalsIgnoreCase("requestedBy")) {
                  column = "requested_by";
              }
  
              if(columnsToUpdate == 0) {
  
                  updateSqlQuery = updateSqlQuery.append("i." + column).append(" = ?");
              } 
              else {
  
                  updateSqlQuery = updateSqlQuery.append(", ");
  
                  updateSqlQuery = updateSqlQuery.append("i." + column).append(" = ?");
              }
  
              columnsToUpdate++;          
          }
  
          updateSqlQuery.append(" where i.id = ?");
  
          logger.info("updateIssuebyIssueId() :: Update Query :: " + updateSqlQuery);
  
          Query query = entityManager.createNativeQuery(updateSqlQuery.toString());
  
          int index = 1;
          int recordsUpdated = 0;
  
          for(String key: customUpdateQuery.keySet()) {
  
          if(key.equalsIgnoreCase("id")) {
              continue;
          }
  
          **if(customUpdateQuery.get(key) == "") {
              logger.info("Setting value to null for key :: " + key);
              query.setParameter(index, null);
          } else {
              query.setParameter(index, customUpdateQuery.get(key));
          }**
  
              index++;
          }
  
          query.setParameter(index, issueId);
  
          logger.info("updateIssuebyIssueId() :: Final Update Query with values :: " + updateSqlQuery);
  
          try {
  
              entityManager.joinTransaction();
  
              recordsUpdated = query.executeUpdate();
  
          }catch(NoResultException e) {
              System.out.println("No records found");
              e.printStackTrace();
              throw new NoResultException();
          }catch (Exception e) {
              System.out.println("Exception encountered");
              e.printStackTrace();
              throw new Exception("Exception encountered");
          }
  
          return recordsUpdated;
  
      }
  </code></pre>
  
  <p>DB Schema information</p>
  
  <pre><code>mysql&gt; desc issue;
  +--------------------------------+--------------+------+-----+---------+-------+
  | Field                          | Type         | Null | Key | Default | Extra |
  +--------------------------------+--------------+------+-----+---------+-------+
  | id                             | varchar(255) | NO   | PRI | NULL    |       |
  | created_by                     | varchar(255) | YES  |     | NULL    |       |
  | created_date                   | datetime     | YES  |     | NULL    |       |
  | last_modified_by               | varchar(255) | YES  |     | NULL    |       |
  | last_modified_date             | datetime     | YES  |     | NULL    |       |
  | customer                       | varchar(255) | YES  |     | NULL    |       |
  | customer_support_ticket_number | varchar(255) | YES  |     | NULL    |       |
  | description                    | varchar(255) | YES  |     | NULL    |       |
  | discovery                      | varchar(255) | YES  |     | NULL    |       |
  | due_date                       | datetime     | YES  |     | NULL    |       |
  | priority                       | varchar(255) | YES  |     | NULL    |       |
  | start_date                     | datetime     | YES  |     | NULL    |       |
  | status                         | varchar(255) | YES  |     | NULL    |       |
  | summary                        | varchar(255) | YES  |     | NULL    |       |
  | team                           | varchar(255) | YES  |     | NULL    |       |
  | component                      | varchar(255) | YES  | MUL | NULL    |       |
  +--------------------------------+--------------+------+-----+---------+-------+
  
  mysql&gt; desc issue_component;
  +--------------------+--------------+------+-----+---------+-------+
  | Field              | Type         | Null | Key | Default | Extra |
  +--------------------+--------------+------+-----+---------+-------+
  | id                 | varchar(255) | NO   | PRI | NULL    |       |
  | created_by         | varchar(255) | YES  |     | NULL    |       |
  | created_date       | datetime     | YES  |     | NULL    |       |
  | last_modified_by   | varchar(255) | YES  |     | NULL    |       |
  | last_modified_date | datetime     | YES  |     | NULL    |       |
  | active             | tinyint(1)   | NO   |     | NULL    |       |
  | description        | varchar(255) | YES  |     | NULL    |       |
  | name               | varchar(255) | YES  |     | NULL    |       |
  | total_issues       | int(11)      | YES  |     | NULL    |       |
  | component_lead     | varchar(255) | YES  | MUL | NULL    |       |
  | project            | varchar(255) | YES  | MUL | NULL    |       |
  +--------------------+--------------+------+-----+---------+-------+
  </code></pre>
  
  <p><strong>Please refer "component" column in the Issue table that refers to the id column in the IssueComponent table</strong></p>