11

对于 Spring Data JPA,我可以使用@GeneratedValue(strategy = GenerationType.AUTO)自定义 id 插入记录,但对于 Spring Data JDBC,如何插入具有自定义 id 的记录?我尝试使用 id 插入,但没有抛出异常并且记录没有插入到表中。

4

2 回答 2

16

使用 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 将抛出异常,导致更新,但更新更新零行,因此这种问题不会被忽视。

于 2018-10-12T05:10:43.203 回答
5

我找到了另一种解决这个问题的方法,虽然有点麻烦。

// 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);

谢谢!

我还在这里添加了评论。

于 2019-01-17T04:25:45.293 回答