如何在Java JPA/Hibernate中设置一个非自动生成的@Id主键?

7
我正在使用Java JPA/Hibernate连接Postgres,并希望将id字段手动生成,即每当我创建此对象的实例时,都会设置id字段。 我已经尝试了几周,但总是遇到以下问题之一:“未找到所需的标识符属性”或“保存后,标识符不能为空”。以下是我使用的模型类的示例:
import javax.persistence.*;

@Entity
@Table(name = "pojo")
public class Pojo {

    @Id
    @Column(name = "id_one")
    private int idOne;

    @Column(name = "bool_example")
    private boolean boolExample;

    public Pojo(){};

    public Pojo(int idOne, boolean boolExample){
        this.idOne = idOne;
        this.boolExample = boolExample;
    }

    public int getIdOne() {
        return idOne;
    }

    public void setIdOne(int idOne) {
        this.idOne = idOne;
    }

    public boolean isBoolExample() {
        return boolExample;
    }

    public void setBoolExample(boolean boolExample) {
        this.boolExample = boolExample;
    }
}

这是我正在调用的样本请求

    @GetMapping(value = "/plswork")
    public String pojotestone(){
        Pojo newpojo = new Pojo(1, false);
        pojoService.saveThis(newpojo);

        pojoService.test();
        return "yes";
    }
pojoService 调用 pojoRepository.save(T entity)。这里的 pojoRepository 继承了 CrudRepository,所以它可以动态创建查询语句。

查看此答案以了解有关 @Id 的一些见解 -> https://dev59.com/XpXfa4cB1Zd3GeqPgIMb。它不会为您生成 PK,只会生成列。 - Sachith Dickwella
尝试使用Integer代替int。同时重写equalshashcode方法。并确保在模式级别上定义了主键。 - the_tech_maddy
@KenChan,这只是从扩展Spring的CrudRepository的pojoRepository中调用save。 - Adam
2
请问为什么您要手动生成ID? - the_tech_maddy
2
为什么不呢?在业务用例中手动ID非常有意义。信用卡类可以将信用卡号作为主键,用户可以将用户名/ID作为主键。这个用例是有效的。 - Adam
显示剩余7条评论
2个回答

5

对于所有想知道的人,

是的-有可能拥有手动id,在某些情况下这是有意义的,例如实体具有固有的id属性(例如信用卡,银行账户等)。

至于这个问题,结果发现与Spring JDBC不兼容。解决方法是使用spring-boot-starter-data-jpa,让存储库继承JPARepository而不是CrudRepository。


0

有几种方法可以在Spring Data JDBC(https://docs.spring.io/spring-data/jdbc/docs/2.2.12/reference/html/#is-new-state-detection)和Spring Data JPA(https://docs.spring.io/spring-data/jpa/docs/2.7.7/reference/html/#jpa.entity-persistence.saving-entites.strategies)中实现。最简单的方法是实现Persistable<YourIdType接口:

@Entity
@Table(name = "pojo")
public class Pojo implements Persistable<Integer>{

    @Id
    @Column(name = "id_one")
    private int idOne;

    @Column(name = "bool_example")
    private boolean boolExample;

    @Transient
    private boolean isNew;

    public setIsNew(boolean isNew) {
       this.isNew = isNew;
    }

    @Override
    public boolean isNew() {
      return isNew; 
    }

    //getters/setters/constructors...

}

现在,如果您想在Java中设置一个ID并保存新实体,只需要调用以下代码:

pojo.setNew(true);
repository.save(pojo);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接