如何使用Spring Data JDBC插入具有自定义ID的记录

har*_*hao 5 java spring insert id-generation spring-data-jdbc

对于Spring Data JPA,我可以使用批注@GeneratedValue(strategy = GenerationType.AUTO)插入具有自定义ID的记录,但是对于Spring Data JDBC,如何插入具有自定义ID的记录?我曾尝试使用id进行插入,但没有引发任何异常,并且记录未插入表中。

Jen*_*der 5

使用Spring Data JDBC进行此操作的方法是注册一个BeforeSaveEvent ApplicationListener创建ID并将其设置在实体中的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());
            }
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

有一个示例说明在Spring Data示例中

您的行未插入表中,但您也没有得到异常的原因是:Spring Data JDBC得出结论,因为设置了ID并执行了更新,所以该实体已经存在。但是由于它不存在,所以更新无法更新任何行,因此什么也没发生。可能值得创建一个改进请求,以将更新计数检查为0。

更新

由于版本1.1 JdbcAggregateTemplate.insert可用,因此您无需进行任何检查就可以进行插入,而不需要检查聚合是否是新的。如果需要,您可以使用它在存储库中创建自定义方法,也可以在需要的地方自动装配模板并直接使用它。

同样,对于DATAJDBC-438,如果保存了聚合,Spring Data JDBC将引发异常,从而导致更新,但是更新更新了零行,因此这种问题不会引起注意。


小智 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);
Run Code Online (Sandbox Code Playgroud)

插入时需要加行user.setNew(true);

谢谢!

我还在这里添加了评论。