[英]How to insert a record with custom id use Spring data jdbc?
对于Spring 数据JPA,我可以使用@GeneratedValue(strategy = GenerationType.AUTO)
插入一条带有自定义id 的记录,但是对于Spring 数据JDBC,我如何插入一条带有自定义id 的记录? 我试图用 id 插入,但没有抛出异常,记录也没有插入到表中。
使用 Spring Data JDBC 做到这一点的方法是注册一个BeforeSaveEvent
ApplicationListener
来创建 id 并将其设置在实体中。
@Bean
public ApplicationListener<BeforeSaveEvent> idSetting() {
return event -> {
if (event.getEntity() instanceof LegoSet) {
LegoSet legoSet = (LegoSet) event.getEntity();
if (legoSet.getId() == null) {
legoSet.setId(createNewId());
}
}
};
}
在Spring Data Examples 中有一个例子证明了这一点
您的行未插入表中但您也没有收到异常的原因是:Spring Data JDBC 得出结论,自设置 ID 并执行更新以来实体已经存在。 但由于它不存在,更新未能更新任何行,所以什么也没发生。 创建改进请求以检查更新计数是否为 0 可能是值得的。
更新
由于版本 1.1 JdbcAggregateTemplate.insert
可用,允许您在不检查聚合是否为新的情况下进行插入。 如果需要,您可以使用它在存储库中创建自定义方法,或者您可以在任何需要的地方自动装配模板并直接使用它。
同样使用 DATAJDBC-438 Spring Data JDBC 会在保存聚合时抛出异常,导致更新但更新更新零行,因此此类问题不会被忽视。
我找到了另一种方法来解决这个问题,虽然有点麻烦。
// BaseEntity
public class BaseEntity implements Persistable, Serializable {
@Id
String id;
@Transient
@JsonIgnore
private boolean newEntity;
@Override
public Object getId() {
return id;
}
public void setNew(boolean newInstance) {
this.newEntity = newInstance;
}
@Override
@JsonIgnore
public boolean isNew() {
return newEntity;
}
}
// User
User extends BaseEntity
...
// insert
User user = new User();
user.id = "5bffb39cc5e30ba067e86dff";
user.setName("xiangzi");
user.setNew(true);
userRepository.save(user);
// update
User user = new User();
user.id = "5bffb39cc5e30ba067e86dff";
user.setName("xiangzi2");
userRepository.save(user);
插入时需要添加一行user.setNew(true);
.
谢谢!
我还在这里添加了评论。
我在上面提到了翔希的回答,并略有不同:
@Data
@Table
public class TestDataTable implements Persistable<String> {
@Id
String id;
private String name;
@Transient
@JsonIgnore
private boolean newEntity;
@Override
public String getId() {
return id;
}
public void setNew(boolean newInstance) {
this.newEntity = newInstance;
}
@Override
@JsonIgnore
public boolean isNew() {
return newEntity;
}
}
// created new record when we use task.setNew(true) in TestDataTable with String Id.
public Mono<TestDataTable> saveTestData(TestDataTable task) {
task.setNew(true);
return testRepository.save(task);
}
我也为限制而苦苦挣扎。 有一些解决方法https://spring.io/blog/2021/09/09/spring-data-jdbc-how-to-use-custom-id-generation ,但它们对我来说不是完美的解决方案。
我正在为 SQLite 开发 Spring 数据 JDBC 集成,它提供了一个存储库助手 class,它公开了 JdbcAggregateTemplate 的insert()
和update()
API( https://github.com/komamitsu/spring-data-sqlhelper ). 该机制不是特定于 SQLite 的,因此我认为尽管需要一些实现,但同样的方法也可以工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.