2016-06-23 5 views
1

私の問題は、エンティティタスクとエンティティUser(Author)の間に双方向のoneToMany関係があることです。これは、スプリング・レストとバネ・データjpaを使用したスプリング・ブート・プロジェクトで実現されています。私がPOSTリクエストでユーザを作成するとうまく動作します。 Author(User)インスタンスなしのTaskを作成した場合も同じです。私はそれを問題なく作り出すことができます。その後、PUTを実行して、ユーザーインスタンスを使用してタスクの作成者を更新しようとします。 Webservice ist 200の答えです。私はまた、タスクテーブルの著者列のユーザーIDを持つデータベースにエントリを持っています。しかし、すべてのユーザーやタスクを取得するGET-Requestを実行すると、何ももう機能しません。郵便配達員はBad Arrayのようなものだけを表示します。そしてなぜ私は考えていない。データベース内のタスクを削除すると、すべて正常に動作します。誰かアイデアを持っている理由は何ですか?ここで クラス:Spring RESTでOneToMany関係を更新する

@Entity 
@Table(name="User") 
public class User { 
@Id 
@GeneratedValue 
@Column(name="USER_ID") 
private Long id; 

@Column(name="CONFIRMATION") 
private boolean confirmed; 

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

@Column(name = "USERNAME",nullable = false) 
@NotNull 
private String userName; 

@Column(name="PASSWORD",nullable = false) 
@NotNull 
private String password; 

@Column(name="TIMESTAMP") 
private Long creationTime; 

@OneToMany(cascade=CascadeType.ALL, mappedBy="author",fetch=FetchType.EAGER) 
private Set<Task>assignedTasks; 

@OneToMany(cascade=CascadeType.ALL, mappedBy="assignee",fetch=FetchType.EAGER) 
private Set<Task>createdTasks; 


public User() { 
} 

public Long getId() { 
    return id; 
} 

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



public String getEmail() { 
    return email; 
} 

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

public String getUserName() { 
    return userName; 
} 

public void setUserName(String userName) { 
    this.userName = userName; 
} 

public String getPassword() { 
    return password; 
} 

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

public Long getCreationTime() { 
    return creationTime; 
} 

public void setCreationTime(Long creationTime) { 
    this.creationTime = creationTime; 
} 

public boolean isConfirmed() { 
    return confirmed; 
} 

public void setConfirmed(boolean confirmed) { 
    this.confirmed = confirmed; 
} 

public Set<Task> getAssignedTasks() { 
    return assignedTasks; 
} 

public void setAssignedTasks(Set<Task> assignedTasks) { 
    this.assignedTasks = assignedTasks; 
} 

public void addAssignedTasks(Task task){ 
    addAssignedTasks(task,true); 
} 

void addAssignedTasks(Task task, boolean set){ 
    if(task != null){ 
     getAssignedTasks().add(task); 
     if(set){ 
      task.setAssignee(this); 
     } 
    } 
} 

public Set<Task> getCreatedTasks() { 
    return createdTasks; 
} 

public void setCreatedTasks(Set<Task> createdTasks) { 
    this.createdTasks = createdTasks; 
} 

public void addCreatedTask(Task task){ 
    addCreatedTask(task,true); 
} 

void addCreatedTask(Task task, boolean set){ 
    if(task != null){ 
     getCreatedTasks().add(task); 
     if(set){ 
      task.setAuthor(this); 
     } 
    } 
} 

public void removeCreatedTask(Task task) { 
    getCreatedTasks().remove(task); 
    task.setAuthor(null); 
} 

}

その後

タスクエンティティ:

@Entity 
@Table(name="Task") 
public class Task { 


@Id 
@GeneratedValue 
@Column(name="TASK_ID") 
private Long id; 

@Transient 
private List<String> possibleTaskTypes = TaskType.getTaskTypesAsString(); 

@Transient 
private List<String>possibleTaskContainer = TaskContainer.getTaskContainerAsString(); 

@Column(name="TASK_Container") 
private String taskContainer; 

@Column(name="TASK_TYPE") 
private String taskType; 

@Column(name="HEAD_LINE") 
private String headLine; 

@Column(name="TASK_TEXT") 
private String taskText; 

@Transient 
private List<String> possibleworkFlowStati = WorkFlowStatus.getWorkFlowsStatiAsString(); 

@Column(name="WORKFLOW_STATUS") 
private String status; 

@ManyToOne(cascade=CascadeType.ALL) 
private User author; 

@ManyToOne(cascade=CascadeType.ALL) 
private User assignee; 

@Column(name="COMMENTS") 
@ElementCollection(targetClass=String.class) 
private List<String>comments; 

@ManyToOne(cascade=CascadeType.ALL) 
private Sprint sprint; 

@Column(name="TIMESTAMP") 
private Long creationTime; 

public Long getId() { 
    return id; 
} 

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

public String getHeadLine() { 
    return headLine; 
} 

public void setHeadLine(String headLine) { 
    this.headLine = headLine; 
} 

public String getTaskText() { 
    return taskText; 
} 

public void setTaskText(String taskText) { 
    this.taskText = taskText; 
} 

public User getAuthor() { 
    return author; 
} 

public void setAuthor(User author) { 
    setAuthor(author, true); 
} 

void setAuthor(User author, boolean add){ 
    this.author = author; 
    if(author !=null&&add){ 
     author.addCreatedTask(this, false); 
    } 
} 

public User getAssignee() { 
    return assignee; 
} 

public void setAssignee(User assignee) { 
    setAssignee(assignee,true); 
} 

void setAssignee(User assignee, boolean add){ 
    this.assignee = assignee; 
    if(assignee != null && add){ 
     assignee.addAssignedTasks(this,false); 
    } 
} 

public List<String> getComments() { 
    return comments; 
} 

public void setComments(List<String> comments) { 
    this.comments = comments; 
} 

public Sprint getSprint() { 
    return sprint; 
} 

public void setSprint(Sprint sprint) { 
    this.sprint = sprint; 
} 

public Long getCreationTime() { 
    return creationTime; 
} 

public void setCreationTime(Long creationTime) { 
    this.creationTime = creationTime; 
} 

public String getTaskType() { 
    return taskType; 
} 

public void setTaskType(String taskType) { 
    this.taskType = taskType; 
} 

public List<String> getPossibleTaskTypes() { 
    return possibleTaskTypes; 
} 

public void setPossibleTaskTypes(List<String> possibleTaskTypes) { 
    this.possibleTaskTypes = possibleTaskTypes; 
} 

public List<String> getPossibleworkFlowStati() { 
    return possibleworkFlowStati; 
} 

public void setPossibleworkFlowStati(List<String> possibleworkFlowStati) { 
    this.possibleworkFlowStati = possibleworkFlowStati; 
} 

public String getStatus() { 
    return status; 
} 

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

public List<String> getPossibleTaskContainer() { 
    return possibleTaskContainer; 
} 

public void setPossibleTaskContainer(List<String> possibleTaskContainer) { 
    this.possibleTaskContainer = possibleTaskContainer; 
} 

public String getTaskContainer() { 
    return taskContainer; 
} 

public void setTaskContainer(String taskContainer) { 
    this.taskContainer = taskContainer; 
} 




} 

今タスクコントローラ:

@RestController 
@RequestMapping("/v1/") 
@Api(value = "tasks", description = "V1 - Tasks API") 
public class TaskController { 

private final Logger logger = LoggerFactory.getLogger(TaskController.class); 
private TaskRepository taskRepository; 
private UserRepository userRepository; 

@Autowired 
public TaskController(TaskRepository taskRepository, UserRepository userRepository){ 
    this.taskRepository = taskRepository; 
    this.userRepository = userRepository; 

} 

protected void verifyTaskById(Long id) throws ResourceNotFoundException{ 
    Task task = taskRepository.findOne(id); 
    if(task == null){ 
     throw new ResourceNotFoundException("Task with ID:"+id+" not found."); 
    } 
} 
/** 
* <b>POST</b> v1/tasks/ 
* @param task 
* @return 
*/ 
@RequestMapping(value="tasks", method=RequestMethod.POST) 
@ApiOperation(value = "Creates a new Task", notes="The newly created Task Id will be sent in the location response header", 
response = Void.class) 
@ApiResponses(value = {@ApiResponse(code=201, message="Task Created Successfully", response=Void.class), @ApiResponse(code=500, message="Error creating Task", response=ErrorDetail.class) }) 
public ResponseEntity<?> createTask(@Valid @RequestBody Task task){ 
    logger.info(task.toString()); 
    task.setCreationTime(new Date().getTime()); 

    task = taskRepository.save(task); 
    HttpHeaders responseHeaders = new HttpHeaders(); 

    URI newTaskUri = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(task.getId()).toUri(); 
    responseHeaders.setLocation(newTaskUri); 

    return new ResponseEntity<>(null, responseHeaders, HttpStatus.CREATED); 
} 

/** 
* <b>GET</b> v1/tasks/ 
* @return 
*/ 
@RequestMapping(value = "tasks", method = RequestMethod.GET) 
@ApiOperation(value = "Retrieves all the tasks", response=Task.class, responseContainer="List") 
public ResponseEntity<Page<Task>> listAllTasks(Pageable pageable){ 
    logger.info("Receiving get-Tasks Request.."); 
    Page<Task> allTasks = taskRepository.findAll(pageable); 
    return new ResponseEntity<>(allTasks,HttpStatus.OK); 
} 

/** 
* <b>GET</b> v1/tasks/{id} 
* @param id 
* @return 
*/ 
@RequestMapping(value = "tasks/{id}", method = RequestMethod.GET) 
@ApiOperation(value = "Retrieves given Task", response=Task.class) 
@ApiResponses(value = {@ApiResponse(code=200, message="", response=Task.class), @ApiResponse(code=404, message="Unable to find Task", response=ErrorDetail.class) }) 
public ResponseEntity<?> getSingleTask(@PathVariable(value="id") Long id){ 
    logger.info("Receiving get Task-Request for ID: "+ id); 
    verifyTaskById(id); 
    Task task = taskRepository.findOne(id); 
    return new ResponseEntity<>(task,HttpStatus.OK); 
} 

/** 
* <b>PUT</b> v1/tasks/{id} 
* @param task 
* @param id 
* @return 
*/ 
@RequestMapping(value = "tasks/{id}", method = RequestMethod.PUT) 
@ApiOperation(value = "Updates given Task", response=Void.class) 
@ApiResponses(value = {@ApiResponse(code=200, message="", response=Void.class), 
     @ApiResponse(code=404, message="Unable to find Task", response=ErrorDetail.class) }) 
public ResponseEntity<?> updateTask(@RequestBody Task task, @PathVariable(value="id") Long id) { 
    logger.info("Receiving put Task Request for "+id); 
    verifyTaskById(id); 
    if(!isIdInBodyCorrect(task, id)){ 
     task.setId(id); 
    } 

    if(task.getAuthor() != null)userRepository.save(task.getAuthor()); 
    if(task.getAssignee()!=null)userRepository.save(task.getAssignee()); 
    Task t = taskRepository.save(task); 

    return new ResponseEntity<>(HttpStatus.OK); 
} 

/** 
* <b>DELETE</b> v1/tasks/{id} 
* 
* @param id 
* @return 
*/ 
@RequestMapping(value = "tasks/{id}", method = RequestMethod.DELETE) 
@ApiOperation(value = "Deletes given Task", response=Void.class) 
@ApiResponses(value = {@ApiResponse(code=200, message="", response=Void.class), 
     @ApiResponse(code=404, message="Unable to find Task", response=ErrorDetail.class) }) 
public ResponseEntity<?> deleteTask(@PathVariable (value="id") Long id) { 
    verifyTaskById(id); 
    taskRepository.delete(id); 
    return new ResponseEntity<>(HttpStatus.OK); 
} 

protected boolean isIdInBodyCorrect(Task task, Long id){ 
    if(task.getId() != id){ 
     logger.warn("Id in Body wasn't defined or wrong. "); //TODO Exception werfen. 
     return false; 
    }else{ 
     return true; 
    } 
} 

} 

そして最後にではなく、少なくともユーザコントローラ:

@RestController 
@RequestMapping("/v1/") 
@Api(value = "users", description = "V1 - Users API") 
public class UserController { 

private final Logger logger = LoggerFactory.getLogger(UserController.class); 

private UserRepository userRepository; 

@Autowired 
public UserController(UserRepository userRepository){ 
    this.userRepository = userRepository; 
} 
/** 
* Checks wether the user exists. If not it throws a {@link ResourceNotFoundException}. 
* @param id 
* @throws ResourceNotFoundException 
*/ 
protected void verifyUserById(Long id) throws ResourceNotFoundException{ 
    User user = userRepository.findOne(id); 
    if(user==null){ 
     throw new ResourceNotFoundException("User with ID:"+id+" not found."); 
    } 
} 
/** 
* <b>POST</b> v1/users/ 
* @param user 
* @return 
*/ 
@RequestMapping(value="users", method=RequestMethod.POST) 
@ApiOperation(value = "Creates a new User", notes="The newly created user Id will be sent in the location response header", 
response = Void.class) 
@ApiResponses(value = {@ApiResponse(code=201, message="User Created Successfully", response=Void.class), @ApiResponse(code=500, message="Error creating User", response=ErrorDetail.class) }) 
public ResponseEntity<?> createUser(@Valid @RequestBody User user) { 
    user.setCreationTime(new Date().getTime()); 
    user = userRepository.save(user); 

    // Set the location header for the newly created resource 
    HttpHeaders responseHeaders = new HttpHeaders(); 
    URI newUserUri = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(user.getId()).toUri(); 
    responseHeaders.setLocation(newUserUri); 

    return new ResponseEntity<>(null, responseHeaders, HttpStatus.CREATED); 
} 
/** 
* <b>GET</b> v1/users/ 
* @return 
*/ 
@RequestMapping(value = "users", method = RequestMethod.GET) 
@ApiOperation(value = "Retrieves all the users", response=User.class, responseContainer="List") 
public ResponseEntity<Page<User>> listAllUsers(Pageable pageable){ 
    Page<User> allUsers = userRepository.findAll(pageable); 
    return new ResponseEntity<>(allUsers,HttpStatus.OK); 
} 

/** 
* <b>GET</b> v1/users/{id} 
* @param id 
* @return 
*/ 
@RequestMapping(value = "users/{id}", method = RequestMethod.GET) 
@ApiOperation(value = "Retrieves given User", response=User.class) 
@ApiResponses(value = {@ApiResponse(code=200, message="", response=User.class), @ApiResponse(code=404, message="Unable to find User", response=ErrorDetail.class) }) 
public ResponseEntity<?> getSingleUser(@PathVariable(value="id") Long id){ 
    verifyUserById(id); 
    User user = userRepository.findOne(id); 
    return new ResponseEntity<>(user,HttpStatus.OK); 
} 
/** 
* <b>PUT</b> v1/users/{id} 
* @param user 
* @param id 
* @return 
*/ 
@RequestMapping(value = "users/{id}", method = RequestMethod.PUT) 
@ApiOperation(value = "Updates given User", response=Void.class) 
@ApiResponses(value = {@ApiResponse(code=200, message="", response=Void.class), 
     @ApiResponse(code=404, message="Unable to find User", response=ErrorDetail.class) }) 
public ResponseEntity<?> updateUser(@RequestBody User user, @PathVariable (value="id") Long id) { 
    verifyUserById(id); 
    // Save the entity 
    if(!isIdInBodyCorrect(user,id)){ 
     user.setId(id); 
    } 
    User u = userRepository.findOne(id); 
    userRepository.save(user); 
    return new ResponseEntity<>(HttpStatus.OK); 
} 

/** 
* <b>DELETE</b> v1/users/{id} 
* @param id 
* @return 
*/ 
@RequestMapping(value="users/{id}", method=RequestMethod.DELETE) 
@ApiOperation(value = "Deletes given User", response=Void.class) 
@ApiResponses(value = {@ApiResponse(code=200, message="", response=Void.class), 
     @ApiResponse(code=404, message="Unable to find User", response=ErrorDetail.class) }) 
public ResponseEntity<?> deleteUser(@PathVariable (value="id") Long id) { 
    verifyUserById(id); 
    userRepository.delete(id); 
    return new ResponseEntity<>(HttpStatus.OK); 
} 

protected boolean isIdInBodyCorrect(User user, Long id){ 
    if(user.getId() != id){ 
     logger.warn("Id in Body wasn't defined or wrong. "); //TODO Exception werfen. 
     return false; 
    }else{ 
     return true; 
    } 
} 



} 
+0

私はあなたが得ている 'erroroneous'レスポンスを投稿すると思います。それは問題をよりよく識別するのに役立ちます –

答えて

1

双方向関係の場合、@ JsonIdentityInfoアノテーションを使用する必要があります。

@JsonIdentityInfoを使用して、双方向関係を持つエンティティのシリアル化を支援する方法を見てみましょう。

@Entity 
@Table(name = "TABLENAME") 
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") 
public class ... { 
関連する問題