API POST REST с сопоставлением «один ко многим»: ошибка не может быть нулевой - PullRequest
0 голосов
/ 09 июня 2019

У меня есть две таблицы: tbl_services & tbl_sub_services. один сервис может иметь несколько подуслуг. Я занимаюсь разработкой REST API с использованием весенней загрузки и пытаюсь разместить данные в таблице services & subservices. Я могу публиковать данные в таблице services, но при публикации в таблице sub-services возникают проблемы. Это one-to-Many Двунаправленное картографирование.

Вот исключение, которое я получаю в почтальоне.

{
"timestamp": "2019-06-09T04:10:22.002+0000",
"status": 500,
"error": "Internal Server Error",
"message": "could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
"trace": "org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement\n\tat 
.
.
.
.
'tbl_services_id' cannot be null\n\tat com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117)\n\tat com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)\n\tat com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:955)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1094)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1042)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1345)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1027)\n\tat com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)\n\tat com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)\n\tat org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175)\n\t... 94 more\n",
"path": "/api/subservices"

Вот структура обеих таблиц:

enter image description here

Классы сущностей:
Services.class

@Entity
@Table(name="tbl_services")
public class Service {

// define fields
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="tbl_services_id")
private int id;

@Column(name="service_name")
private String serviceName;

@Column(name="service_desc")
private String serviceDesc;

@Column(name="service_image")
private String serviceImage;

@OneToMany(mappedBy="service",
        cascade= {CascadeType.PERSIST, CascadeType.MERGE,
            CascadeType.DETACH, CascadeType.REFRESH})
private List<SubService> subServices;

public List<SubService> getSubServices() {
    return subServices;
}

public void setSubServices(List<SubService> subServices) {
    this.subServices = subServices;
}
}

SubService.class

@Entity
@Table(name="tbl_sub_services")
public class SubService {

// define fields
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="tbl_sub_services_id")
private int id;

@ManyToOne(
        cascade= {CascadeType.PERSIST, CascadeType.MERGE,
                CascadeType.DETACH, CascadeType.REFRESH})
@JoinColumn(name="tbl_services_id")
@JsonIgnore
private Service service;

public Service getService() {
    return service;
}

@Column(name="sub_service_name")
private String subServiceName;

@Column(name="sub_service_desc")
private String subServiceDesc;

@Column(name="sub_service_image")
private String subServiceImage;

Я пытаюсь отправить данные от почтальона, затем получаю исключение. Вот данные, которые я выкладываю от почтальона.

enter image description here

Вот вспомогательные сервисы HibernateDAOImpl.class

@Override
public void saveSubService(SubService theSubService) {
    // get the current hibernate session
    Session currentSession = entityManager.unwrap(Session.class);
    System.out.println("SubService object : "+theSubService);       
    currentSession.saveOrUpdate(theSubService);
}  

РЕДАКТИРОВАТЬ: Вот полезная нагрузка json, которую я получаю в методе saveSubService:

[id=0, service=null, subServiceName=GST, subServiceDesc=GST is a subservice which currently having , subServiceImage=path-to-image]

1 Ответ

1 голос
/ 09 июня 2019

Вы получаете:

не удалось выполнить оператор; SQL [н / п]; ограничение [ноль]

Я вижу, что вы передаете service в запросе, но я не вижу, чтобы вы загружали его до сохранения SubService:

@Override
public void saveSubService(SubService theSubService) {
    Session currentSession = entityManager.unwrap(Session.class);
    Service loadedService = currentSession.load(Service.class
           , theSubService.getService.getId();

    theSubService.setService(loadedService);         

    currentSession.saveOrUpdate(theSubService);
}

или попробуйте просто объединить, поскольку у вас уже есть надлежащий каскад:

@Override
public void saveSubService(SubService theSubService) {
    // get the current hibernate session
    Session currentSession = entityManager.unwrap(Session.class);
    System.out.println("SubService object : "+theSubService);       
    currentSession.merge(theSubService);
}

Кроме того, я не уверен, зачем вам unwrap сеанс. EntityManager и его интерфейс будет достаточным в этом случае.

...