CRUD API Spring 引导复制一个条目
CRUD API Spring Boot Make a Copy of an entry
我正在尝试制作我从 CRUD 存储库中获取的实例的副本。我想存储实例的副本但具有不同的主键。在我在服务 class 中制作的复制方法中,当我尝试制作副本时,它抛出一个错误提示 org.hibernate.HibernateException: identifier of an instance of SpringBootStarter.Topic.Topic was altered from <id> to <new_id>
当我点击 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;
}
}
下面是控制器Class
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);
}
}
下面是服务Class
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);
}
}
下面是主题库
import org.springframework.data.repository.CrudRepository;
public interface TopicRepository extends CrudRepository<Topic, String> {
}
持久性上下文保存着所有实体的生命周期。当您获取实体时,它将成为该交易中的附加实体。因为你的对象的引用没有改变,持久化上下文会知道它在数据库中仍然是同一个对象,不允许它的标识符改变。
如果要创建新条目,则必须使用 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 时会遇到很多陷阱。在不了解最基本知识的情况下开始使用它绝不是一个好主意。
我正在尝试制作我从 CRUD 存储库中获取的实例的副本。我想存储实例的副本但具有不同的主键。在我在服务 class 中制作的复制方法中,当我尝试制作副本时,它抛出一个错误提示 org.hibernate.HibernateException: identifier of an instance of SpringBootStarter.Topic.Topic was altered from <id> to <new_id>
当我点击 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;
}
}
下面是控制器Class
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);
}
}
下面是服务Class
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);
}
}
下面是主题库
import org.springframework.data.repository.CrudRepository;
public interface TopicRepository extends CrudRepository<Topic, String> {
}
持久性上下文保存着所有实体的生命周期。当您获取实体时,它将成为该交易中的附加实体。因为你的对象的引用没有改变,持久化上下文会知道它在数据库中仍然是同一个对象,不允许它的标识符改变。
如果要创建新条目,则必须使用 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 时会遇到很多陷阱。在不了解最基本知识的情况下开始使用它绝不是一个好主意。