2014-03-13 14 views
6

Lassen Sie mich zuerst meinen Anwendungsfall erklären. Es ist ziemlich geradlinig. Es gibt eine Benutzer-Entität und eine Service-Entität. Ich habe eine ManytoMany-Verknüpfung zwischen Benutzer und Dienst, die UserService als Joined-Entität (verknüpfte Tabelle) verwendet. Anfangs wird es einige Benutzer und einige Dienste geben. Benutzer können zu jedem Zeitpunkt einen beliebigen Dienst abonnieren. In diesem Fall wird ein Eintrag zu UserService hinzugefügt. Aber ich erhalte eine Null-Zeiger-Ausnahme, als ich versuchte, eine neue UserService-Verbindung zu erstellen. Ich könnte Benutzer und Service individuell erstellen.Feder Datenrest ManytoMany POST

Meine Entities sind: 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()); 
    } 

} 

Service-Entity

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()); 
    } 

} 

Und die schließlich Einheit

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()); 
    } 

} 

beitreten Jetzt mein Problem, GET-Anfragen funktionieren ordnungsgemäß, aber ich bekomme Nullzeiger Ausnahme, wenn ich versuche, einen neuen UserService zu erstellen.

POST: http://localhost:8080/em/api/userServices/ Ich versuche, Benutzer 1 mit Service zu assoziieren 2 Anfrage:

{ 
    "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"` 
    } 
} 

Fehler 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\"])" 
} 

GET http://localhost:8080/em/api/userServices liefert mir die folgende Ausgabe:

{ 
    "_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 
    } 
} 

Hat jemand erfolgreich die ManyToMany-Assoziation mit Spring-data-rest implementiert? Wenn ja, bitte helfen Sie mir in dieser Hinsicht

+3

alle über das Internet, siehe i Beispiele, aber keine Beispiele für die Buchung oder Puting einer Ressource mit Verbänden – user1917034

Antwort

3

Ich fand das Problem und habe es funktioniert.

Zuvor meine Anfrage Körper war:

{ 
    "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" 
    } 
} 

Ich fand heraus, dass es die folgenden sein sollte:

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

Ich fühle mich dort mit Feder-data-Rest noch ein Problem. Bitte klären Sie, wenn jemand anders fühlt. Sogar mit der festen Anfrage erhielt ich NULL-Constraint für ServiceId. Ich fand heraus, in db, die primäre Schlüsselspalte für Service war service_id. Auch wenn ich die Entity korrekt zugeordnet habe (Meine Id-Eigenschaft in Service Entity ist ordnungsgemäß zu service_id in db zugeordnet), funktionierte es nicht, ich musste den Spaltennamen in id ändern, damit dies funktionierte.

Spring-Data-Rest sollte abhängig von der Entity-Mappings für Id richtig? Wenn ja, dann gibt es immer noch einen Fehler.

Danke, Vivek

+0

Ihre Frage über die Id sollten als separate Frage gestellt werden. Hat Ihre service_id die @Id-Annotation? Wenn nicht, war das wahrscheinlich dein Problem. – JBCP