当前位置: 首页 > 知识库问答 >
问题:

Hibernate saveOrUpdate()保存但不更新

方飞翼
2023-03-14

我正在学习hibernate和Spring Boot(也是Thymeleaf),遇到了以下问题:

环境:我有一个表单,处理创建和更新数据基于ID参数在GET方法,如果ID等于数据库中的一行,那么更新,否则保存。ID存储在隐藏的输入标记中,并与表单数据一起插入到实体对象中。然后将该对象发送给一个服务,该服务调用DAO来使用saveOrUpdate()方法保存或更新数据。

问题总结:在我的服务中,我有一个用@Transactional注释的方法,它调用我的DAO,然后它打开一个会话并执行saveOrUpdate()。问题是,这段代码正确地将新数据保存到我的数据库中,但它不更新现有数据,在日志中saveOrUpdate()只选择而不插入。

我得HTML表单与Thymeleaf

<form action="#" th:action="@{saveCustomer}" th:object="${newCustomer}" method="post">
            <input type="hidden" th:field="*{id}" />
            <table>
                <tr>
                    <td><label>First Name:</label></td>
                    <td><input type="text" th:field="*{firstName}"/></td>
                </tr>
                <tr>
                    <td><label>Last Name:</label></td>
                    <td><input type="text" th:field="*{lastName}"/></td>
                </tr>
                <tr>
                    <td><label>Email:</label></td>
                    <td><input type="text" th:field="*{email}"/></td>
                </tr>
                <tr>
                    <td><label></label></td>
                    <td><input type="submit" value="Submit" class="save"/></td>
                </tr>
                <tr>
                    <td><label></label></td>
                    <td><input type="reset" value="Reset" class="save"/></td>
                </tr>
            </table>
        </form>

控制器方法

    @PostMapping("/saveCustomer")
    public String saveCustomer(@ModelAttribute("newCustomer") Customer newCustomer) {
        customerService.saveCustomer(newCustomer);
        return "redirect:/list";
    }

服务方式

import javax.transaction.Transactional;

    @Override
    @Transactional
    public void saveCustomer(Customer newCustomer) {
        customerDAO.saveCustomer(newCustomer);
    }
    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Override
    public void saveCustomer(Customer newCustomer) {
        try (Session session = entityManagerFactory.unwrap(SessionFactory.class).openSession()) {
//            If I use transaction like this everything works correctly!
//            Transaction transaction = session.beginTransaction();
            session.saveOrUpdate(newCustomer);
//            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
import javax.persistence.*;

@Entity
@Table(name = "customer")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    public int getId() {
        return id;
    }

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

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}
Hibernate: select customer0_.id as id1_0_, customer0_.email as email2_0_, customer0_.first_name as first_na3_0_, customer0_.last_name as last_nam4_0_ from customer customer0_ order by customer0_.last_name
Hibernate: select customer0_.id as id1_0_0_, customer0_.email as email2_0_0_, customer0_.first_name as first_na3_0_0_, customer0_.last_name as last_nam4_0_0_ from customer customer0_ where customer0_.id=?
Hibernate: select customer0_.id as id1_0_, customer0_.email as email2_0_, customer0_.first_name as first_na3_0_, customer0_.last_name as last_nam4_0_ from customer customer0_ order by customer0_.last_name

我省略了declutter代码的大部分导入,因为我只包含了对象中与问题相关的部分。

共有1个答案

漆雕唯
2023-03-14

您导入的@transactional批注错误。它应该来自包org.springframework.transaction.annotation。这里是这个注释的API文档-https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/transactional.html

此外,您还可以使用Spring Data JPA,并使用JPA存储库简化数据库操作,因为它们有许多易于使用和方便的方法。使用Spring Data JPA,只需创建存储库接口(如下所示),调用其方法来保存数据:

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {}

在服务中,自动连接这个存储库,并调用它的save方法:

@Autowired
private CustomerRepository customerRepository;

@org.springframework.transaction.annotation.Transactional
public Customer saveOrUpdate(Customer customer) {
    return customerRepository.save(customer); // this will save or update (if id is there)
}
 类似资料:
  • 我有一个Spring应用程序,其中Domain Object标识符不是由数据库分配的,而是由应用程序生成的。标识符是在BeforeSave回调期间生成并添加到Domain Object中的。保存域对象(插入)后,当尝试保存具有相同标识符的域对象(更新)时,我收到以下错误 原因:组织。springframework。道。Incorrectupdatesemanticdataaccessexcepti

  • 问题内容: 在此请忍受,因为这个问题与我使用React,Redux或react- redux的第一个测试应用有关。Docs使我步入正轨,并且我有一个可以正常工作的模拟银行应用程序。我的状态对象大致如下所示: 我只有两个动作: 1. CHANGE_HASH(如网址哈希中所示)。此操作始终按预期工作,而reducer所做的只是更新state.activePageId(是的,我正在克隆状态对象而不是对其

  • 一个被提交了的改动会被永久地保存在仓库(repository)中。然而,在你日常工作中你经常需要“暂时地”保存一下你的一些本地改动。例如,如果你正在开发一个新的功能,但是与此同时又得到了一个错误报告,并且需要马上修复它,而你现在的本地改动又和这个错误毫无关系,因此你必须暂时地停止新功能的开发,来开始着手修复这个错误。并且你还想要保存那些已完成的开发工作,以便之后能继续来完成它。 像这样的情况会随时

  • 我试图实现一个链表类在C和我有问题。我有添加新节点的=运算符。 链接列表类接口: 这里我有=重载实现: 此外,我还有“数组”访问重载方法: 一切正常-我检查了dibugger, 问题是-=不在“head”中保存新节点- 有人知道为什么新的分配没有链接到头- 谢谢!!

  • 问题内容: 我有一个用@Transactional注释的方法。我从Oracle数据库检索一个对象,更改一个字段,然后从该方法返回。我忘了保存对象,但是发现无论如何都会更新数据库。 applicationContext 我的方法 我的问题是为什么MyObject会持久保存到数据库? 问题答案: 因为hibernate将自动检测对持久实体所做的更改并相应地更新数据库。hibernate参考手册的第11

  • 我有一个模型 视图定位对象: 然后它会做出一些改变(或者可能不会) 然后它尝试保存任何更改: 这里是Django尝试插入另一行而不是更新的地方,导致了一个DB错误 解决方案中有一种类似的问题: 一旦我将primary_key字段设置为自动字段,问题就消失了。 但是,我的主键已经是一个自动字段。 所以我用调试器逐步浏览了django代码,并在文件中资助了这个: 似乎如果没有更改(因此更新不做任何事情