我正在学习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代码的大部分导入,因为我只包含了对象中与问题相关的部分。
您导入的@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代码,并在文件中资助了这个: 似乎如果没有更改(因此更新不做任何事情