You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CRUD站点更新博客时新增而非修改问题求助

问题

开发小型CRUD站点时,更新现有博客文章未修改原内容,反而创建了新文章,已确认ID参数传递正确。

相关控制器代码:

@PostMapping("/edit/{id}")
public String blogPostEdit(@PathVariable(value = "id") long id,@RequestParam String title, @RequestParam String summary, @RequestParam String fullText, /*@AuthenticationPrincipal MyAppUser currentUser,*/ Model model){
    Blog blog = blogRepository.findById(id).orElseThrow();
    blog.setTitle(title);
    blog.setSummary(summary);
    blog.setFullText(fullText);
    blogRepository.save(blog);
    return "redirect:/home";
}

博客实体类代码:

@Entity
public class Blog {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String title;
    private String summary;
    private String fullText;
    private String author;
    private int views;

    public Blog() {
    }

    public Blog(String title, String summary, String fullText, String author) {
        this.title = title;
        this.summary = summary;
        this.fullText = fullText;
        this.author = author;
    }

    // getter和setter方法
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    public String getSummary() { return summary; }
    public void setSummary(String summary) { this.summary = summary; }
    public String getFullText() { return fullText; }
    public void setFullText(String fullText) { this.fullText = fullText; }
    public String getAuthor() { return author; }
    public void setAuthor(String author) { this.author = author; }
    public int getViews() { return views; }
    public void setViews(int views) { this.views = views; }
}

解决办法

1. 添加事务管理

Spring Data JPA的save方法判断是更新还是插入,依赖实体处于持久化上下文。如果控制器方法没有事务,查询出的实体会变成游离状态,save时会触发插入。在blogPostEdit方法上添加@Transactional注解:

@PostMapping("/edit/{id}")
@Transactional
public String blogPostEdit(@PathVariable(value = "id") long id,@RequestParam String title, @RequestParam String summary, @RequestParam String fullText, Model model){
    Blog blog = blogRepository.findById(id).orElseThrow();
    // 可选:打印日志确认ID是否正确
    // System.out.println("Updating blog ID: " + blog.getId());
    blog.setTitle(title);
    blog.setSummary(summary);
    blog.setFullText(fullText);
    blogRepository.save(blog);
    return "redirect:/home";
}

2. 检查Repository实现

确保blogRepository继承自JpaRepository<Blog, Long>,Spring Data JPA的默认实现会正确处理更新逻辑:

public interface BlogRepository extends JpaRepository<Blog, Long> {
}

3. 验证实体ID状态

在更新前打印查询到的实体ID,确认ID与传入的参数一致,避免出现ID被意外重置的情况。

4. 分层架构优化(推荐)

将业务逻辑移至Service层,在Service方法上添加@Transactional,控制器仅处理请求转发:

// BlogService.java
@Service
public class BlogService {
    private final BlogRepository blogRepository;

    public BlogService(BlogRepository blogRepository) {
        this.blogRepository = blogRepository;
    }

    @Transactional
    public void updateBlog(Long id, String title, String summary, String fullText) {
        Blog blog = blogRepository.findById(id).orElseThrow();
        blog.setTitle(title);
        blog.setSummary(summary);
        blog.setFullText(fullText);
        blogRepository.save(blog);
    }
}

// 控制器修改
@PostMapping("/edit/{id}")
public String blogPostEdit(@PathVariable(value = "id") long id,@RequestParam String title, @RequestParam String summary, @RequestParam String fullText, Model model){
    blogService.updateBlog(id, title, summary, fullText);
    return "redirect:/home";
}

内容的提问来源于stack exchange,提问作者Faer Bot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 03:11:13