【问题标题】:POST REST API with One-To-Many Mapping : Cannot be null error具有一对多映射的 POST REST API:不能为空错误
【发布时间】:2019-06-09 04:19:48
【问题描述】:

我有两张桌子:tbl_services & tbl_sub_services。一项服务可以有多个子服务。我正在使用 spring boot 开发 REST API 并尝试在服务和子服务表中发布数据。我可以在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"

这是两个表的结构:

实体类:
服务类

@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;

我正在尝试从邮递员那里发布数据,然后出现异常。这是我从邮递员那里发布的数据。

这里是 SubServicesHibernateDAOImpl.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);
}  

编辑: 这是我在 saveSubService 方法中收到的 json 有效负载:

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

【问题讨论】:

    标签: java hibernate rest spring-boot one-to-many


    【解决方案1】:

    你得到:

    无法执行语句; SQL [不适用];约束 [null]

    我看到您在请求中传递了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 及其接口在这种情况下就足够了。

    【讨论】:

    • 如果我使用merge,那么它给了我同样的异常,我在问题中发布了,如果我使用第一个解决方案,那么它给我Service loadedService = currentSession.load(Service.class , theSubService.getService.getId();中的空指针异常
    • 您确定“服务”已正确映射到对象吗?在那种情况下我似乎没有
    • 这是我在 saveSubService 方法中接收到的 json 有效负载:` [id=0, service=null, subServiceName=GST, subServiceDesc=GST 是一个子服务,目前有,subServiceImage=path-to-image ]`
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 2012-12-08
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-01
    相关资源
    最近更新 更多