Spring Data Rest ManytoMany POST [英] Spring Data Rest ManytoMany POST

查看:114
本文介绍了Spring Data Rest ManytoMany POST的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,让我解释一下我的用例。这很直接。有一个用户实体和一个服务实体。我使用UserService作为连接实体(连接表)在User和Service之间有很多关联。最初,会有一些用户和一些服务集。用户可以随时订阅任何服务。在这种情况下,将向UserService添加一个条目。但是,当我尝试创建一个新的UserService关联时,我得到空指针异常。我可以单独创建用户和服务。

First, let me explain my usecase. It's pretty straight forward. There is a User entity and a Service entity. I have ManytoMany association between User and Service using UserService as the Joined entity (joined table) Initially,there will be some set of users and some set of services. Users can subscribe to any Service at any point of time. In that case, an entry will be added to UserService. But, I am getting null pointer exception when i tried to create a new UserService association. I could create User and Service individually.

我的实体是:
User.java

My Entities are : User.java

package dao.models;

import java.io.Serializable;
import javax.persistence.*;

import com.fasterxml.jackson.annotation.JsonBackReference;
@Entity
@org.hibernate.annotations.Proxy(lazy=false)
@Table(name="`user`", schema="emm")
public class User implements Serializable {
    public User() {
    }

    @Column(name="id", nullable=false, unique=true) 
    @Id 
    @GeneratedValue(generator="EMM_USER_ID_GENERATOR")  
    @org.hibernate.annotations.GenericGenerator(name="EMM_USER_ID_GENERATOR", strategy="native")    
    private long id;


    @ManyToOne(targetEntity=dao.models.Tenant.class, fetch=FetchType.LAZY)  
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.LOCK})    
    @JoinColumns({ @JoinColumn(name="tenant_id", referencedColumnName="id", nullable=false) })  
    @org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.NO_PROXY)  
    private dao.models.Tenant tenant;

    @OneToOne(targetEntity=dao.models.Person.class, fetch=FetchType.LAZY)   
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK}) 
    @JoinColumns({ @JoinColumn(name="Person_id", nullable=false) }) 
    @org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.NO_PROXY)  
    private dao.models.Person person;

    @Column(name="password", nullable=true, length=255) 
    private String password;

    @Column(name="email", nullable=false, length=255)   
    private String email;

    @Column(name="status", nullable=true, length=255)   
    private String status;

    @ManyToMany(mappedBy="user", targetEntity=dao.models.TenantGroup.class) 
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK}) 
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)  
    private java.util.List<dao.models.TenantGroup> group = new java.util.ArrayList<dao.models.TenantGroup>();

    @OneToMany(mappedBy="user", targetEntity=dao.models.UserService.class)  
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK}) 
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)  
    private java.util.List<dao.models.UserService> userService = new java.util.ArrayList<dao.models.UserService>();

    public void setId(long value) {
        this.id = value;
    }

    public long getId() {
        return id;
    }



    public void setPassword(String value) {
        this.password = value;
    }

    public String getPassword() {
        return password;
    }

    public void setEmail(String value) {
        this.email = value;
    }

    public String getEmail() {
        return email;
    }

    public void setStatus(String value) {
        this.status = value;
    }

    public String getStatus() {
        return status;
    }

    public void setTenant(dao.models.Tenant value) {
        this.tenant = value;
    }

    public dao.models.Tenant getTenant() {
        return tenant;
    }

    public void setPerson(dao.models.Person value) {
        this.person = value;
    }

    public dao.models.Person getPerson() {
        return person;
    }

    public void setGroup(java.util.List<dao.models.TenantGroup> value) {
        this.group = value;
    }

    public java.util.List<dao.models.TenantGroup> getGroup() {
        return group;
    }




    public java.util.List<dao.models.UserService> getUserService() {
        return userService;
    }

    public void setUserService(
            java.util.List<dao.models.UserService> userService) {
        this.userService = userService;
    }

    public String toString() {
        return String.valueOf(getId());
    }

}

服务实体

package dao.models;

import java.io.Serializable;
import javax.persistence.*;

import com.fasterxml.jackson.annotation.JsonBackReference;
@Entity
@org.hibernate.annotations.Proxy(lazy=false)
@Table(name="service", schema="emm")
public class Service implements Serializable {
    public Service() {
    }

    @Column(name="service_id", nullable=false, unique=true) 
    @Id 
    @GeneratedValue(generator="EMM_SERVICE_SERVICE_ID_GENERATOR")   
    @org.hibernate.annotations.GenericGenerator(name="EMM_SERVICE_SERVICE_ID_GENERATOR", strategy="native") 
    private long id;

    @Column(name="service_name", nullable=false, length=255)    
    @org.hibernate.annotations.Index(name="service_service_name")   
    private String serviceName;

    @Column(name="description", nullable=true, length=255)  
    private String description;

    @Column(name="app_key", nullable=false, length=255) 
    private String appKey;

    @Column(name="app_token", nullable=false, length=255)   
    private String appToken;

    @Column(name="learnmoreurl",  length=255)   
    private String learnMoreURL;

    @Column(name="trialurl",  length=255)   
    private String trialURL;

    @ManyToMany(mappedBy="service", targetEntity=dao.models.Device.class)   
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK}) 
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)  
    private java.util.List<dao.models.Device> device = new java.util.ArrayList<dao.models.Device>();

    @OneToMany(mappedBy="service", targetEntity=dao.models.ServiceParam.class)  
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})   
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)  
    private java.util.List<dao.models.ServiceParam> serviceParams = new java.util.ArrayList<dao.models.ServiceParam>();

    @OneToMany(mappedBy="service", targetEntity=dao.models.TenantService.class) 
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.MERGE,
                                        org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})    
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)  
    private java.util.List<dao.models.TenantService> tenantService = new java.util.ArrayList<dao.models.TenantService>();

    @OneToMany(mappedBy="service", targetEntity=dao.models.UserService.class)   
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})   
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)  
    private java.util.List<dao.models.UserService> userService = new java.util.ArrayList<dao.models.UserService>();

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getServiceName() {
        return serviceName;
    }


    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getAppKey() {
        return appKey;
    }

    public void setAppKey(String appKey) {
        this.appKey = appKey;
    }

    public String getAppToken() {
        return appToken;
    }

    public void setAppToken(String appToken) {
        this.appToken = appToken;
    }

    public String getLearnMoreURL() {
        return learnMoreURL;
    }
    public void setLearnMoreURL(String learnMoreURL) {
        this.learnMoreURL = learnMoreURL;
    }

    public String getTrialURL() {
        return trialURL;
    }

    public void setTrialURL(String trialURL) {
        this.trialURL = trialURL;
    }

    public java.util.List<dao.models.Device> getDevice() {
        return device;
    }


    public void setDevice(java.util.List<dao.models.Device> device) {
        this.device = device;
    }

    public java.util.List<dao.models.ServiceParam> getServiceParams() {
        return serviceParams;
    }

    public void setServiceParams(
            java.util.List<dao.models.ServiceParam> serviceParams) {
        this.serviceParams = serviceParams;
    }

    public java.util.List<dao.models.TenantService> getTenantService() {
        return tenantService;
    }

    public void setTenantService(
            java.util.List<dao.models.TenantService> tenantService) {
        this.tenantService = tenantService;
    }

    public java.util.List<dao.models.UserService> getUserService() {
        return userService;
    }

    public void setUserService(
            java.util.List<dao.models.UserService> userService) {
        this.userService = userService;
    }
    public String toString() {
        return String.valueOf(getId());
    }

}

最后加入实体

UserService.java

UserService.java

package dao.models;

import java.io.Serializable;
import javax.persistence.*;
@Entity
@org.hibernate.annotations.Proxy(lazy=false)
@Table(name="user_service" ,schema="emm")
public class UserService implements Serializable {
    public UserService() {
    }

    @Column(name="id", nullable=false, unique=true) 
    @Id 
    @GeneratedValue(generator="EMM_USER_SERVICE_ID_GENERATOR")  
    @org.hibernate.annotations.GenericGenerator(name="EMM_USER_SERVICE_ID_GENERATOR", strategy="native")    
    private long id;

    @ManyToOne(targetEntity=dao.models.User.class, fetch=FetchType.LAZY)    
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.LOCK})    
    @JoinColumns({ @JoinColumn(name="user_id", referencedColumnName="id", nullable=false) })    
    @org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.NO_PROXY)  
    private dao.models.User user;

    @ManyToOne(targetEntity=dao.models.Service.class, fetch=FetchType.LAZY) 
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.LOCK})    
    @JoinColumns({ @JoinColumn(name="service_id", referencedColumnName="service_id", nullable=false) }) 
    @org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.NO_PROXY)  
    private dao.models.Service service;

    @Column(name="param_name", nullable=false)  
    private String paramName;

    @Column(name="param_value", nullable=true)  
    private String paramValue;

    @OneToMany(mappedBy="userService", targetEntity=dao.models.UserServiceToken.class)  
    @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK}) 
    @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)  
    private java.util.List<dao.models.UserServiceToken> userServiceToken = new java.util.ArrayList<dao.models.UserServiceToken>();



    public long getId() {
        return id;
    }



    public void setId(long id) {
        this.id = id;
    }



    public dao.models.User getUser() {
        return user;
    }



    public void setUser(dao.models.User user) {
        this.user = user;
    }



    public dao.models.Service getService() {
        return service;
    }



    public void setService(dao.models.Service service) {
        this.service = service;
    }



    public String getParamName() {
        return paramName;
    }



    public void setParamName(String paramName) {
        this.paramName = paramName;
    }



    public String getParamValue() {
        return paramValue;
    }



    public void setParamValue(String paramValue) {
        this.paramValue = paramValue;
    }



    public java.util.List<dao.models.UserServiceToken> getUserServiceToken() {
        return userServiceToken;
    }



    public void setUserServiceToken(
            java.util.List<dao.models.UserServiceToken> userServiceToken) {
        this.userServiceToken = userServiceToken;
    }



    public String toString() {
        return String.valueOf(getId());
    }

}

现在我的问题,GET请求是正常工作,但是,当我尝试创建一个新的UserService时,我得到空指针异常。

Now my issue, GET requests are working properly, But, I get null pointer exception when I try to create a new UserService.

POST: http:// localhost:8080 / em / api / userServices /
我试图将用户1与服务2关联
请求:

POST : http://localhost:8080/em/api/userServices/ I am trying to associate user 1 with service 2 Request :

{
    "paramName": "p1",
    "paramValue": "v1",
    "service": {
        "href": `"http://localhost:8080/em/api/userServices/1/service/2"`
    },
    "user": {
        "href": `"http://localhost:8080/em/api/userServices/1/user/1"`
    }
}

错误Messgae:

{
    "cause": {
        "cause": {
            "cause": null,
            "message": null
        },
        "message": "(was java.lang.NullPointerException) (through reference chain: dao.models.UserService[\"service\"])"
    },
    "message": "Could not read JSON: (was java.lang.NullPointerException) (through reference chain: dao.models.UserService[\"service\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: dao.models.UserService[\"service\"])"
}

获取 http:// localhost:8080 / em / api / userServices 给我以下输出:

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/em/api/userServices{?page,size,sort}",
      "templated" : true
    }
  },
  "_embedded" : {
    "userServices" : [ {
      "paramName" : "p1",
      "paramValue" : "v1",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/em/api/userServices/1"
        },
        "userServiceToken" : {
          "href" : "http://localhost:8080/em/api/userServices/1/userServiceToken"
        },
        "user" : {
          "href" : "http://localhost:8080/em/api/userServices/1/user"
        },
        "service" : {
          "href" : "http://localhost:8080/em/api/userServices/1/service"
        }
      }
    }, {
      "paramName" : "pone",
      "paramValue" : "vone",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/em/api/userServices/2"
        },
        "userServiceToken" : {
          "href" : "http://localhost:8080/em/api/userServices/2/userServiceToken"
        },
        "user" : {
          "href" : "http://localhost:8080/em/api/userServices/2/user"
        },
        "service" : {
          "href" : "http://localhost:8080/em/api/userServices/2/service"
        }
      }
    } ]
  },
  "page" : {
    "size" : 20,
    "totalElements" : 2,
    "totalPages" : 1,
    "number" : 0
  }
}

有没有人成功实施过ManyToMany使用Spring-data-rest的社交。如果是这样,请在这方面帮助我

Has anyone successfully implemented ManyToMany association using Spring-data-rest. If so, kindly help me in this regard

推荐答案

我找出了问题并使其正常运作。

I figured out the issue and got it working.

以前,我的申请机构是:

Previously, my request body was:

{
    "paramName": "p1",
    "paramValue": "v1",
    "service": {
        "href": "http://localhost:8080/em/api/userServices/1/service/2"
    },
    "user": {
        "href": "http://localhost:8080/em/api/userServices/1/user/1"
    }
}

我发现它应该如下:

{
    "paramName": "p1",
    "paramValue": "v1",
    "service":  "http://localhost:8080/em/api/services/2",
    "user":  "http://localhost:8080/em/api/users/1"
 }

我觉得spring-data-rest仍然存在问题。如果有人不这样做,请澄清一下。即使有固定的请求,我也得到了ServiceId的空约束。我在db中发现,服务的主键列是service_id。即使我有正确的实体映射(服务实体中的我的Id属性正确映射到db中的service_id),但它无法正常工作,我不得不将列名更改为id以使其正常工作。

I feel there is still an issue with spring-data-rest. Kindly clarify, if anyone feels otherwise. Even with the fixed request, i was getting null constraint for ServiceId. I figured out in db, the primary key column for service was service_id. Even though, I have the entity mapping properly (My Id property in Service Entity maps properly to service_id in db), it was not working, I had to change the column name to id to get this working.

Spring-Data-Rest应该依赖于Id的实体映射吗?如果是这样,那么仍有一个错误。

Spring-Data-Rest should depending upon the Entity mappings for Id right ? If so, then Still there is a bug.

谢谢,
Vivek

Thanks, Vivek

这篇关于Spring Data Rest ManytoMany POST的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆