Java CRUD API Spring Boot创建条目的副本

Java CRUD API Spring Boot创建条目的副本,java,spring-boot,hibernate,crud,Java,Spring Boot,Hibernate,Crud,我试图复制一个从CRUD存储库获取的实例。我想用不同的主键存储实例的副本。在我在服务类中创建的copy方法中,当我尝试创建一个副本时,它抛出一个错误,称为org.hibernate.hibernateeexception:SpringBootStarter.Topic.Topic实例的标识符在创建副本后,当我在postman上点击GET请求时被更改为,我希望在结果中同时看到原始和副本(但副本具有不同的主键) 谁能帮帮我吗 import javax.persistence.Entity; imp

我试图复制一个从CRUD存储库获取的实例。我想用不同的主键存储实例的副本。在我在服务类中创建的copy方法中,当我尝试创建一个副本时,它抛出一个错误,称为
org.hibernate.hibernateeexception:SpringBootStarter.Topic.Topic实例的标识符在创建副本后,当我在postman上点击GET请求时被更改为
,我希望在结果中同时看到原始和副本(但副本具有不同的主键)

谁能帮帮我吗


import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Topic {

    @Id
    private String id;
    private String name;
    private String description;

    public Topic(){

    }

    public Topic(String id, String name, String description) {
        this.id = id;
        this.name = name;
        this.description = description;
    }

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
下面是控制器类


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class TopicController {

    @Autowired
    private TopicService topicService;

    @GetMapping("/topics")
    public List<Topic> getAllTopics(){
        return topicService.getAllTopics();
    }

    @GetMapping("/topics/{id}")
    public Topic getTopic(@PathVariable String id){
        return topicService.getTopic(id);
    }

    @PostMapping("/topics")
    public void addTopic(@RequestBody Topic topic){
        topicService.addTopic(topic);
    }

    @PostMapping("topics/{id}/{new_id}")
    public void copyTopic(@PathVariable String id, @PathVariable String new_id){
        topicService.copyTopic(id, new_id); }

    @PutMapping("/topics/{id}")
    public void updateTopic(@RequestBody Topic topic, @PathVariable String id){
        topicService.updateTopic(topic, id);
    }

    @DeleteMapping("/topics/{id}")
    public void deleteTopic(@PathVariable String id){
        topicService.deleteTopic(id);
    }
}
package SpringBootStarter.Topic;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class TopicService {

    @Autowired
    private TopicRepository topicRepository;

    public List<Topic> getAllTopics(){
        List<Topic> topics = new ArrayList<>();
        topicRepository.findAll().forEach(topics :: add);

        return topics;
    }

    public Topic getTopic(String id){
        Optional<Topic> optional = topicRepository.findById(id);
        return optional.get();
    }

    public void addTopic(Topic topic){
        topicRepository.save(topic);
    }

    public void copyTopic(String id, String new_id){
        Topic topic = topicRepository.findById(id).get();
        Topic topicCopy = topic;
        topicCopy.setId(new_id);
        addTopic(topicCopy);
    }

    public void updateTopic(Topic topic, String id){
        topicRepository.save(topic);
    }

    public void deleteTopic(String id){
        topicRepository.deleteById(id);
    }

}

导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.web.bind.annotation.*;
导入java.util.List;
@RestController
公共类主题控制器{
@自动连线
私人TopicService TopicService;
@GetMapping(“/topics”)
公共列表getAllTopics(){
返回topicService.getAllTopics();
}
@GetMapping(“/topics/{id}”)
公共主题getTopic(@PathVariable字符串id){
返回topicService.getTopic(id);
}
@后映射(“/主题”)
public void addTopic(@RequestBody Topic){
topicService.addTopic(topic);
}
@后期映射(“主题/{id}/{new_id}”)
公共无效copyTopic(@PathVariable字符串id、@PathVariable字符串新id){
topicService.copyTopic(id,new_id);}
@PutMapping(“/topics/{id}”)
public void updateTopic(@RequestBody主题,@PathVariable字符串id){
topicService.updateTopic(主题,id);
}
@删除映射(“/topics/{id}”)
public void deleteTopic(@PathVariable字符串id){
topicService.deleteTopic(id);
}
}
以下是服务类别


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class TopicController {

    @Autowired
    private TopicService topicService;

    @GetMapping("/topics")
    public List<Topic> getAllTopics(){
        return topicService.getAllTopics();
    }

    @GetMapping("/topics/{id}")
    public Topic getTopic(@PathVariable String id){
        return topicService.getTopic(id);
    }

    @PostMapping("/topics")
    public void addTopic(@RequestBody Topic topic){
        topicService.addTopic(topic);
    }

    @PostMapping("topics/{id}/{new_id}")
    public void copyTopic(@PathVariable String id, @PathVariable String new_id){
        topicService.copyTopic(id, new_id); }

    @PutMapping("/topics/{id}")
    public void updateTopic(@RequestBody Topic topic, @PathVariable String id){
        topicService.updateTopic(topic, id);
    }

    @DeleteMapping("/topics/{id}")
    public void deleteTopic(@PathVariable String id){
        topicService.deleteTopic(id);
    }
}
package SpringBootStarter.Topic;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class TopicService {

    @Autowired
    private TopicRepository topicRepository;

    public List<Topic> getAllTopics(){
        List<Topic> topics = new ArrayList<>();
        topicRepository.findAll().forEach(topics :: add);

        return topics;
    }

    public Topic getTopic(String id){
        Optional<Topic> optional = topicRepository.findById(id);
        return optional.get();
    }

    public void addTopic(Topic topic){
        topicRepository.save(topic);
    }

    public void copyTopic(String id, String new_id){
        Topic topic = topicRepository.findById(id).get();
        Topic topicCopy = topic;
        topicCopy.setId(new_id);
        addTopic(topicCopy);
    }

    public void updateTopic(Topic topic, String id){
        topicRepository.save(topic);
    }

    public void deleteTopic(String id){
        topicRepository.deleteById(id);
    }

}
包SpringBootStarter.Topic;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.stereotype.Service;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Optional;
@服务
公共类主题服务{
@自动连线
私人专题报道专题报道;
公共列表getAllTopics(){
列表主题=新建ArrayList();
topicRepository.findAll().forEach(topics::add);
返回主题;
}
公共主题(字符串id){
Optional=topicRepository.findById(id);
返回可选的.get();
}
公共void addTopic(主题){
topicRepository.save(主题);
}
public void copyTopic(字符串id、字符串新id){
Topic Topic=topicRepository.findById(id.get();
Topic topicCopy=主题;
topicCopy.setId(新的_id);
添加主题(主题副本);
}
public void updateTopic(主题,字符串id){
topicRepository.save(主题);
}
公共无效删除主题(字符串id){
topicRepository.deleteById(id);
}
}
下面是主题库


import org.springframework.data.repository.CrudRepository;

public interface TopicRepository extends CrudRepository<Topic, String> {


}

导入org.springframework.data.repository.crudepository;
公共接口TopicRepository扩展了Crudepository{
}

持久性上下文包含所有实体的生命周期。获取实体时,它将是该transsaction中的附加实体。因为对象的引用没有更改,所以持久性上下文将知道它仍然是数据库中的同一个对象,不允许其标识符更改。 如果要创建一个新条目,必须使用
new
关键字创建一个新对象并将其持久化

因此,与其像这样更改标识符

public void copyTopic(String id, String new_id){
    Topic topic = topicRepository.findById(id).get();
    Topic topicCopy = topic;
    topicCopy.setId(new_id);
    addTopic(topicCopy);
}
创建一个新的主题实体,并像这样保持它

public void copyTopic(String id, String new_id){
    Topic topic = topicRepository.findById(id).get();
    Topic topicCopy = new Topic(topic);
    topicCopy.setId(new_id);
    addTopic(topicCopy);
}
我的建议是通读Hibernate的基础知识,因为使用ORM时有很多陷阱。在不了解基本知识的情况下开始使用它从来都不是一个好主意