gpt4 book ai didi

java - 使用 Spring REST 更新一对多关系

转载 作者:行者123 更新时间:2023-11-30 07:18:33 25 4
gpt4 key购买 nike

我的问题是我在实体任务和实体用户(作者)之间有一个双向的 oneToMany 关系。这是在 Spring Boot 项目中使用 Spring Rest 和 Spring Data JPA 实现的。如果我通过 POST-Request 创建用户,它工作正常。如果我创建一个没有作者(用户)实例的任务,情况也是如此。我可以毫无困难地创建它。之后,我尝试通过执行 PUT 使用用户实例更新任务的作者。网络服务的答案是 200 好的。我还在数据库中找到了一个条目,其用户 ID 位于任务表的作者列中。但是,当我执行 GET-Request 来获取所有用户或任务时,一切都不起作用了。 Postman 仅显示诸如 Bad Array 之类的内容。我不知道为什么。如果我删除数据库中的任务,一切都会恢复正常。有谁知道为什么吗?这里是类(class):

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




}

现在是任务 Controller :

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

}

最后但并非最不重要的用户 Controller :

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



}

最佳答案

如果您有双向关系,则必须使用 @JsonIdentityInfo 注释。

让我们看看如何使用 @JsonIdentityInfo 帮助序列化具有双向关系的实体。

@Entity
@Table(name = "TABLENAME")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ... {

关于java - 使用 Spring REST 更新一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37986928/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com