问题描述
我在玩 spring-data-jdbc 并发现了一个问题,我无法使用 Google 解决.
无论我尝试做什么,我都无法将一个琐碎的对象推送到数据库中(Bean1.java:25):carRepository.save(new Car(2L, "BMW", "5"));
No matter what I try to do, I just can't push a trivial object into the database (Bean1.java:25):
carRepository.save(new Car(2L, "BMW", "5"));
两者,没有一个和一个 TransactionManager +@Transactional
数据库(显然)不会提交记录.
Both, without one and with a TransactionManager +@Transactional
the database (apparently) does not commit the record.
代码基于 Postgres 数据库,但您也可以简单地使用下面的 H2 并获得相同的结果.
这是(简约的)源代码:https://github.com/bitmagier/spring-data-jdbc-sandbox/tree/stackoverflow-question
Here is the (minimalistic) source code: https://github.com/bitmagier/spring-data-jdbc-sandbox/tree/stackoverflow-question
谁能告诉我,为什么汽车没有插入数据库?
Can somebody tell me, why the car is not inserted into the database?
推荐答案
这与事务不工作无关.相反,它是关于 Spring Data JDBC,考虑到您的实例是需要更新(而不是插入)的现有实例.
This is not related to transactions not working. Instead, it's about Spring Data JDBC considering your instance an existing instance that needs updating (instead of inserting).
您可以通过激活日志记录 用于 org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
.您应该看到 update
但没有 insert
.
You can verify this is the problem by activating logging for org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
. You should see an update
but no insert
.
默认情况下,当一个实体的 id 为对象类型且值为 null
或原始类型(例如 int
或 long
) 和 0
的值.如果您的实体具有带有 @Version
注释的属性,则该属性将用于确定实例是否为新实例.
By default, Spring Data JDBC considers an entity as new when it has an id of an object type and a value of null
or of a primitive type (e.g. int
or long
) and a value of 0
.
If your entity has an attribute with @Version
annotation that attribute will be used to determine if the instance is a new one.
为了使其工作,您有以下选择:
You have the following options in order to make it work:
将 id 设置为
null
并配置您的数据库模式,以便在插入时自动创建一个新值.保存后,您的实体实例将包含从数据库生成的值.
Set the id to
null
and configure your database schema so that it will automatically create a new value on insert. After the save your entity instance will contain the generated value from the database.
注意:Spring Data JDBC 将设置 id,即使它在您的实体中是最终的.
保留 id null
并在 Before-Save 侦听器中将其设置为所需的值.
Leave the id null
and set it in a Before-Save listener to the desired value.
让你的实体实现 可持久的
.这允许您控制何时将实体视为新.您可能还需要一个侦听器,以便让实体知道它不再是新的.
Let your entity implement Persistable
. This allows you to control when an entity is considered new. You'll probably need a listener as well so you can let the entity know it is not new any longer.
从 Spring Data JDBC 1.1 版开始,您还可以使用 JdbcAggregateTemplate
进行直接插入,无需检查 id,请参阅 https://jira.spring.io/browse/DATAJDBC-282
.当然,您可以在存储库的自定义方法中执行此操作,如本示例中所做的那样:https://github.com/spring-projects/spring-data-examples/pull/441
Beginning with version 1.1 of Spring Data JDBC you'll also be able to use a JdbcAggregateTemplate
to do a direct insert, without inspecting the id, see https://jira.spring.io/browse/DATAJDBC-282
. Of course, you can do that in a custom method of your repository, as is done in this example: https://github.com/spring-projects/spring-data-examples/pull/441
这篇关于为什么 Spring-data-jdbc 不保存我的 Car 对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!