简体   繁体   English

具有非唯一ID的表中的JPA实体

[英]JPA entity from a table with non-unique id

I want to have an entity 我想要一个实体

class InkFormula {
    int id;
    Map<Ink, Integer> inkPercents;        
    ...
}

from a single table with such a structure: 从具有这种结构的单个表中:

┌─────┬────────┬─────────┐
│ id  │ ink_id │ percent │
├─────┼────────┼─────────┤
│  1  │   1    │   50    │
├─────┼────────┼─────────┤
│  1  │   2    │   25    │
├─────┼────────┼─────────┤
│  1  │   3    │   0     │
├─────┼────────┼─────────┤
│  2  │   1    │   100   │
├─────┼────────┼─────────┤
│  2  │   2    │   80    │
└─────┴────────┴─────────┘

where non-unique id must be used to congregate a Map<> from ink_id and percent . 其中必须使用非唯一idink_idpercent ink_id Map<>

The reason why I need a single entity and a single table is a requirement to have unique constraint id , ink_id so that each formula could not contain repeated inks. 我需要单个实体和单个表的原因是要求具有唯一的约束idink_id以便每个公式都不能包含重复的油墨。

Is that possible with JPA and Hibernate? JPA和Hibernate有可能吗?

I would create a composite primary key InkFormulaId which contains two fields: id and ink_id similar to 我将创建一个复合主键InkFormulaId ,其中包含两个字段: idink_id类似于

@Embeddable
public class InkFormulaId implements Serializable {

    private Integer id;

    private Integer inkId;

    // ...
}

@Entity
public class InkFormula {

    @EmbeddedId
    private InkFormulaId inkFormulaId;

    @ManyToOne
    @MapsId(value = "inkId")
    private Ink ink;

    private Integer percents;

    // ...
}

so each InkFormula represents a single line in your table above with a unique primary key ( id , inkId ) and their percents . 因此,每个InkFormula代表上方表中的一行,带有唯一的主键( idinkId )及其percents

To get the mapping you mentioned above, you would have to SELECT all InkFormula for a single id and then group them by inkId in your Java code. 为了获得上面提到的映射,您必须为单个id SELECT所有InkFormula ,然后在Java代码中按inkId将它们inkId

An alternative solution could be using an @ElementCollection annotation and separating data into two tables: 另一种解决方案是使用@ElementCollection批注并将数据分为两个表:

ink_formula    ink_formula_ink_percent
  ┌───┐    ┌──────────────┬──────┬───────┐
  │id │    │ink_formula_id│ink_id│percent│
  ├───┤    ├──────────────┼──────┼───────┤
  │ 1 │    │       1      │   1  │   20  │
  ├───┤    ├──────────────┼──────┼───────┤
  │ 2 │    │       1      │   2  │   55  │
  ├───┤    ├──────────────┼──────┼───────┤
  . . .    . . . . . . . . . . . . . . . . 

The entity class will then look like 实体类将如下所示

@Entity
public class InkFormula {
    @Id
    @GeneratedValue
    int id;      

    @ElementCollection
    @CollectionTable(
            name="ink_formula_ink_percent",
            joinColumns=@JoinColumn(name="ink_formula_id")
    )
    @MapKeyJoinColumn(name="ink_id")
    @Column(name = "percent")
    private Map<Ink, Integer> inkPercents = new TreeMap<>();

    //...    
}

This setup satisfies the unique InkFormula-Ink requirement but we need a separate table for InkFormula . 此设置满足InkFormula-Ink的独特要求,但是我们需要一个单独的InkFormula表。

Next question is how to ensure the uniqueness of each InkFormula since two InkFormulas with different id s can hold the same values in their inkPercents maps. 下一个问题是如何确保每个InkFormula的唯一性,因为具有不同id的两个InkFormulas可以在其inkPercents映射中保留相同的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM