JPA中的实体序列生成器

Posted

技术标签:

【中文标题】JPA中的实体序列生成器【英文标题】:Sequence generator by entity in JPA 【发布时间】:2018-04-19 19:30:20 【问题描述】:

我正在尝试使用 JPA 在 mysql 中创建一个顺序生成器字段,对于任何实体,“prod_generator_id”必须以“1”开头。 示例:

这是我的 java 对象:

//this one is working fine, the id is unique...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "pro_id")
private Long id;

//here is the problem, must start in "1" by entity
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="seq")
@SequenceGenerator(name="seq", sequenceName="pro_id_tenancy", initialValue=1, allocationSize=1)
@Column(name = "pro_id_tenancy")
private Long idTenancyProjeto;

我正在使用 spring boot,但是当我保存对象时,idTenancyProjeto 将变为空。

我找到的最简单的解决方案:只需计算该公司的产品数量,然后在我的 product.save() 中添加+1,仅此而已,就可以了。谢谢大家。

【问题讨论】:

检查***.com/questions/4102449/… 我已经用更多信息更新了这个问题。 为了让这个问题看起来很完整,我希望至少有两个类声明(Corporation 和 Product)。此外,“保存对象”的代码示例会很好。 【参考方案1】:

据我了解,您希望某公司的所有产品在该公司内从 1 到 n 编号。

映射它的可能性取决于您使用的 JPA 提供程序。

要在 Hibernate 中实现这一点(从 4.3 开始),您可以将索引集合(通过@OneToMany)与@ListIndexBase 结合使用(参见https://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/annotations/ListIndexBase.html)。

示例代码:

@Entity
class Corporation 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "corp_id")
    private Long id;

    @OneToMany(mappedBy="corporation")
    @OrderColumn(name="prod_generator_id")
    @ListIndexBase(1)
    private List<Product> products;

    public List<Product> getProducts()  
         return products;
    

    public void setProducts(List<Product> products) 
       this.products = products;
    


@Entity
class Product 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "prod_id")
    private Long id;

    @ManyToOne
    @JoinColumn(
        name = "corp_id", 
        referencedColumnName = "corp_id"
    )
    private Corporation corporation;

    public Corporation getCorporation() 
        return corporation;
    

    public void setCorporation(Corporation corporation) 
        this.corporation = corporation;
    

另一种香草 JPA 方法可能是使用 @PrePersist@PreUpdate

@Entity
class Corporation 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "corp_id")
    private Long id;

    @OneToMany(mappedBy="corporation", cascade = CascadeType.ALL)
    @OrderBy("prodGeneratorId")
    private List<Product> products;

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    public List<Product> getProducts() 
         return products;
    

    public void setProducts(List<Product> products) 
       this.products = products;
    


@Entity
class Product 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "prod_id")
    private Long id;

    @Column(name = "prod_generator_id")
    private Integer prodGeneratorId;

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    @ManyToOne
    @JoinColumn(
        name = "corp_id",
        referencedColumnName = "corp_id"
    )
    private Corporation corporation;

    public Corporation getCorporation() 
        return corporation;
    

    public void setCorporation(Corporation corporation) 
        this.corporation = corporation;
    

    public Integer getProdGeneratorId() 
        return prodGeneratorId;
    

    private void setProdGeneratorId(Integer prodGeneratorId) 
        this.prodGeneratorId = prodGeneratorId;
    

    @PrePersist
    @PreUpdate
    public void updateProdGeneratorId() 
        setProdGeneratorId(getCorporation().getProducts().indexOf(this) + 1);
    

【讨论】:

也许您应该向 OP 提及这是什么 @ListIndexBase,因为它不是 JPA 的一部分,因此该应用程序是不可移植的。此外,OP 没有说明使用了哪个 JPA 提供程序,因此您必须具备一些先见之明...【参考方案2】:

解决方案:

作为最简单的解决方案,我制作了另一个总计的表格,在保存之前我得到了 e add+1 的值。

【讨论】:

以上是关于JPA中的实体序列生成器的主要内容,如果未能解决你的问题,请参考以下文章

jpa序列ID生成

多方类中的JPA Key生成

JPA 使用指南 /Eclipselink/JPA 实体生成器

JPA 序列生成器说增量大小与 DB 中的值不同

单个实体 Spring Data JPA 中的“自动生成的 PK 作为 Id”和“自动生成的 UUID 作为字符串”

IDEA生成JPA实体类