【问题标题】:Why does Spring-data-jdbc not save my Car object?为什么 Spring-data-jdbc 不保存我的 Car 对象?
【发布时间】:2018-10-26 13:27:40
【问题描述】:

我正在使用 spring-data-jdbc 并发现了一个问题,我无法使用 Google 解决。

无论我尝试做什么,我都无法将一个琐碎的对象推送到数据库中(Bean1.java:25): carRepository.save(new Car(2L, "BMW", "5"));

两者,没有一个和一个 TransactionManager +@Transactional 数据库(显然)不会提交记录。

代码基于 Postgres 数据库,但您也可以简单地使用下面的 H2 并获得相同的结果。

这是(简约的)源代码: https://github.com/bitmagier/spring-data-jdbc-sandbox/tree/stackoverflow-question

谁能告诉我,为什么汽车没有插入数据库?

【问题讨论】:

标签: java insert spring-data-jdbc


【解决方案1】:

这与交易不工作无关。 相反,它是关于 Spring Data JDBC 考虑您的实例是需要更新(而不是插入)的现有实例。

您可以通过activating loggingorg.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate 验证这是问题所在。您应该会看到 update,但看不到 insert

默认情况下,当一个实体的 id 为对象类型且值为null 或原始类型(例如intlong)且值为@ 时,Spring Data JDBC 默认将实体视为新实体987654330@。 如果您的实体具有带有 @Version 注释的属性,则该属性将用于确定实例是否为新实例。

为了使其工作,您有以下选择:

  1. 将 id 设置为 null 并配置您的数据库架构,以便在插入时自动创建一个新值。保存后,您的实体实例将包含从数据库生成的值。

    注意:Spring Data JDBC 将设置 id,即使它在您的实体中是最终的。

  2. 保留 id null 并在 Before-Save 侦听器中将其设置为所需的值。

  3. 让您的实体实现Persistable。这允许您控制何时将实体视为。您可能还需要一个监听器,以便让实体知道它不再是新的。

  4. 从 Spring Data JDBC 1.1 版开始,您还可以使用 JdbcAggregateTemplate 进行直接插入,而无需检查 id,请参阅 https://jira.spring.io/browse/DATAJDBC-282。当然,您可以在存储库的自定义方法中执行此操作,如本示例中所做的那样:https://github.com/spring-projects/spring-data-examples/pull/441

【讨论】:

  • 我昨天问了一个类似的问题,Jens 很好地将我的问题与这个问题联系起来,我确认这个答案基本上使我的问题重复了。所以我只想对 Jens 表示感谢。谢谢詹斯!
  • 这仅适用于聚合根吗?我刚刚注意到我有一个子类,它在持久性之前在客户端代码中设置它的 PK(它使用 UUID,仅供参考),它似乎工作得很好。
  • 简短回答:是的,有点。长答案请单独提问。
猜你喜欢
  • 2012-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
  • 2019-01-26
  • 1970-01-01
  • 2010-12-04
  • 2015-09-19
相关资源
最近更新 更多