Я новичок в разработке весенних загрузочных приложений и сталкиваюсь со следующей проблемой.
Я работаю с приложением, в котором разрабатываю отслеживаемые проблемы.Каждая проблема может быть связана с определенной категорией.Однако не обязательно связывать проблему с определенной категорией.
Проблемы могут быть созданы без привязки их к какой-либо конкретной категории.Проблемы могут быть обновлены для просмотра существующего списка категорий.Проблемы могут быть обновлены, чтобы очистить связанную категорию и сохранить категорию как NULL.
В третьем случае я столкнулся со следующей проблемой, описанной ниже в журнале регистрации исключений.
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) ==> value ::: ()
2019-03-02 23:07:56.856 INFO 3984 --- [nio-8080-exec-9] c.a.m.A.controller.IssueController : Key ::: (id) ==> 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)
Я определил сущности следующим образом
Issue.java
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<String> {
@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 */
}
IssueComponent.java
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<String> {
@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<Issue> issues;
/* getters & setters */
}
IssueServiceImpl.java
@Override
@Transactional
public int updateIssuebyIssueId(String issueId, Map<String, String> 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 && (key.equalsIgnoreCase("createdBy"))
|| (key.equalsIgnoreCase("modifiedBy"))) {
continue;
}
String column = key;
if(key != null && key.equalsIgnoreCase("status")) {
// issueStatusUpdated = true;
}
if(key != null && key.equalsIgnoreCase("epicStatus")) {
column = "epic_status";
}
if(key != null && key.equalsIgnoreCase("issueType")) {
column = "issue_type";
}
if(key != null && key.equalsIgnoreCase("dueDate")) {
column = "due_date";
}
if(key != null && key.equalsIgnoreCase("startDate")) {
column = "start_date";
}
if(key != null && key.equalsIgnoreCase("assignedToUser")) {
column = "assigned_to_user";
}
if(key != null && 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;
}
Информация о схеме БД
mysql> 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> 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 | |
+--------------------+--------------+------+-----+---------+-------+
Пожалуйста, обратитесь к столбцу "компонент" в таблице проблем, которая ссылаетсяк столбцу id в таблице IssueComponent