加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

java – Spring JPA存储库:阻止保存更新

发布时间:2020-12-15 01:32:14 所属栏目:大数据 来源:网络整理
导读:我的用户数据库表如下所示: CREATE TABLE user ( username VARCHAR(32) PRIMARY KEY,first_name VARCHAR(256) NOT NULL,last_name VARCHAR(256) NOT NULL,password VARCHAR(32) NOT NULL,enabled BOOL) ENGINE = InnoDB; 这是我的实体的字段定义: @Entityp

我的用户数据库表如下所示:

CREATE TABLE user (
    username VARCHAR(32) PRIMARY KEY,first_name VARCHAR(256) NOT NULL,last_name VARCHAR(256) NOT NULL,password VARCHAR(32) NOT NULL,enabled BOOL
) ENGINE = InnoDB;

这是我的实体的字段定义:

@Entity
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private String firstName;

    @Column(nullable = false)
    private String lastName;

    @Column(nullable = false)
    private String password;

字段用户名是我的表/实体的密钥,由我来设置其值.
当我需要创建另一个用户时,我在我的服务中执行此操作:

public User insertUserImpl(String username,String firstName,String lastName) {
    Assert.hasText(username);
    Assert.hasText(firstName);
    Assert.hasText(lastName);

    String password = UUID.randomUUID().toString().substring(0,4); // temp
    User user = new User(username,password);
    user.setFirstName(firstName);
    user.setLastName(lastName);
    user.setEnabled(false);
    this.userRepository.save(user);
    // FIXME - assegnare un ruolo
    return user;
}

无论如何,如果已经使用了用户名,则存储库只进行更新,因为指定的标识符不为空.这不是我想要的行为,我需要它抛出类似重复的条目异常.
有什么方法可以预防吗?我必须自己做吗?
例如.:

User user = this.userRepository.findOne(username);
if(user != null) {
    throw new RuntimeException("Username already taken"); // FIXME - eccezione applicativa
}
最佳答案
当使用默认配置,并使用CrudRepository#save()或JpaRepository#save()时,它将委托给EntityManager,如果它是新实体则使用persists(),如果不是则使用merge().

当使用默认配置时,遵循以下策略来检测实体状态,无论是否为新,使用适当的方法如下:

>默认情况下,执行Property-ID检查,如果为null,则它是新实体,否则不是.
>如果实体实现Persistable,则检测将委托给实体实现的isNew()方法.
>有第三个选项,实现EntityInformation,但需要进一步的自定义.

source

因此,在您的情况下,当您使用用户名作为ID,并且它不为空时,Repository调用最终委托给EntityManager.merge()而不是persist().所以有两种可能的解决方案:

>使用不同的ID属性,将其设置为null,并使用任何自动生成方法,或
> make user实现Persistable并使用isNew()方法确定它是否是新实体.

如果由于某种原因,您不想修改实体,还可以更改修改刷新模式配置的行为.默认情况下,在spring数据jpa中,hibernate flush模式设置为AUTO.你想要做的是将它更改为COMMIT,并且要更改它的属性是org.hibernate.flushMode.您可以通过覆盖@Configuration类中的EntityManagerFactoryBean来修改此配置.

如果您不想弄乱EntityManager的配置,可以使用JpaRepository#flush()或JpaRepository#saveAndFlush()方法将挂起的更改提交到数据库.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读