【问题标题】:spring JPA CRUD Repository and updating a recordspring JPA CRUD 存储库和更新记录
【发布时间】:2015-10-04 23:21:15
【问题描述】:

这是一个关于带有 Hibernate 和 PostgreSQL 的 Spring Boot MVC 应用程序的问题。

我有一个网页,允许用户为应用程序设置管理/配置数据,我想将这些数据存储在单个数据库记录中。我有一个 POJO 来包含数据。我编写了一个保存这些数据的 Spring MVC 应用程序。

问题在于,每次用户保存数据(通过从网页执行 POST)时,Spring 应用程序都会在数据库中创建一条新记录。

我正在使用存储库,我的印象是,每次我对对象执行 Repository.save() 时,它都会更新现有记录(如果有的话),否则创建一个新记录并且它会根据主键识别记录。我找不到“更新”方法。

我已经尝试了几种解决此问题的方法,但它们要么仍然制作额外的记录,要么因重复键错误而失败,要么根本不起作用。

另外,似乎每次我启动网页或应用程序时,数据库中的所有数据都会被删除。

那么有什么诀窍呢?非常感谢...

这是我的代码:

AdminFormController.java

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.beans.factory.annotation.Autowired;


@Controller
public class Admin_FormController 
{

    @Autowired
    private AdminDataRepository rep;

    @RequestMapping(value="/admin", method=RequestMethod.GET)
    public String adminForm(Model model) 
    {
        AdminData ad = new AdminData();
        model.addAttribute("adminForm", ad);

        ad = rep.findById(1L);

        if(ad != null)
            ad.setId(1L);

        return "adminForm";
    }

    @RequestMapping(value="/admin", method=RequestMethod.POST)
    public String adminSubmit(@ModelAttribute AdminData ad, Model model) 
    {

        // ad.setId(1L);;

        rep.save(ad);

        model.addAttribute("adminForm", ad);

        return "adminForm";
    }
}

AdminDataRepository.java

import org.springframework.data.repository.CrudRepository;

public interface AdminDataRepository extends CrudRepository<AdminData, String> 
{
    AdminData findById(Long Id);
}

AdminData.java

import java.util.logging.Logger;
import javax.persistence.*;

@Entity
public class AdminData 
{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)   
    private Long id;

    private String useDates;

    private String startDate;
    private String endDate;

    public String getUseDates()
    {
        return useDates;
    }


    public String getStartDate() 
    {
        return startDate;
    }

    public String getEndDate() 
    {
        return endDate;
    }

    public void setUseDates(String s)
    {
        Logger.getGlobal().info(() -> "UseDates: " + s);
        useDates = s;
    }

    public void setStartDate(String s) 
    {
        Logger.getGlobal().info(() -> "Start Date: " + s);
        startDate = s;
    }

    public void setEndDate(String s) 
    {
        Logger.getGlobal().info(() -> "End Date: " + s);
        endDate = s;
    }

}

【问题讨论】:

    标签: spring hibernate spring-mvc jpa


    【解决方案1】:

    您需要将对象存储在请求之间的某处。您的选择:

    1. 使用隐藏的表单域
    2. 从数据库中重新读取它(在您的 POST 方法中)
    3. 使用会话

    1 不方便,也不安全。 2 不支持并发控制。 3 是安全且正确的。

    要实现 #3,请在 controller 之前添加 @SessionAttributes("yourAttributeName")。将SessionStatus 参数添加到您的POST 方法,并在完成后调用sessionStatus.setComplete()

    例如here

    【讨论】:

    • 哇,这真的很容易,谢谢!我的目的是在用户单击“保存”后将其留在此页面上,以便他们继续进行更改。他们从这里获得的确实没有上层菜单或页面。所以没有机会调用 sessionStatus.setComplete() 方法。这会导致问题吗?
    • @JimArcher 如果您不调用 setComplete,至少在用户会话结束之前,您最终会使用更多的服务器内存。您可能需要运行一个定期进程来清理 sessionAttributes,或者忍受一点额外的内存使用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    相关资源
    最近更新 更多