【问题标题】:JPA -Table column references as foreign key to two different tablesJPA - 表列引用作为两个不同表的外键
【发布时间】:2018-04-11 15:29:36
【问题描述】:

亲爱的开发者你好,

我目前的情况:我正在使用 JPA 2.1,并且在一个表中,我有一列在外键关系中引用了两个不同的表。

这在 JPA 中如何描述?

Table Book 
  taxRateId (manyToOne) (GermanTax/AustrianTax)
  countryType

Table GermanTax
  taxRateId (oneToMany Books)

Table AustrianTax
  taxRateId (oneToMany Books)


CONSTRAINT germanTax FOREIGN KEY (tax_rate_id) REFERENCES german_tax (id)

CONSTRAINT austrianTax FOREIGN KEY (tax_rate_id) REFERENCES austrian_tax (id),

【问题讨论】:

  • 在 GermanTax 和 AustrianTax 中,taxRateId 列是主键吗?
  • 另一个问题:你能指定表之间的关系吗?
  • 嗨,是的 taxRateId 列是主键。我还在括号中描述了关系

标签: mysql jpa foreign-keys one-to-many many-to-one


【解决方案1】:

我想出了这种映射方法:

@Entity 
@Inheritance(InheritanceType.TABLE_PER_CLASS)
public abstract class Tax {
    @Id
    @Column(name = "taxRateId")
    //@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "pk-sequence")
    //@SequenceGenerator(name = "pk-sequence", sequenceName = "ID_GEN", allocationSize = 1)
    protected Long taxRateId = -1;

    public long getTaxRateId() {
        return taxRateId;
    } 

    @Column(nullable=false)
    private double taxRate;

    @Column(nullable=false)
    private String countryName; // countryType ?

    // getters and setters for 'taxRate' and `countryName`
}

接下来,我们定义两个具体的Tax实体,如下所示:

@Entity
public class AustrianTax extends Tax {
    // nothing special here, the type differentiates enough
}

@Entity
public class GermanTax extends Tax {
    // nothing special here, see above --^
}

然后,我们以通用方式将Book 映射到Tax

/*
 * As you brought up the question
 */
@Entity
public class Book {
    // fields & annotations for ID attribute and generation strategy, similar to above

    @OneToMany
    private Set<Tax> countryRates;

    // getters and setters, add and remove for 'countryRates' 
}

然而,将其定义如下会更精确 - 并且符合 3NF 中的数据模型:

/*
 * One book can refer to 1 or more rates (Austrian/German) AND 
 * One rate can be applied to 1 or more books -> @ManyToMany
 */
@Entity
public class Book {
    // fields & annotations for ID attribute and generation strategy, similar to above

    @ManyToMany
    private Set<Tax> countryRates;

    // getters and setters, add and remove for 'countryRates' 
}

后一种情况的一般假设/基本原理 (@ManyToMany):

某本书(同一本书)在不同国家/地区销售,税率不同。因此,如果可以的话,我的建议是更改数据库架构(表结构)。这将/将产生一个 n:m 表来映射关系

|Book| 0..* &lt;--&gt; 0..* |Tax|

正确(在语义上)。脚注:我希望你还处于开发的早期阶段。

唯一剩下的是属性countryType,我无法将其关联为Book 类型的属性,假设一本书没有针对奥地利方言进行修改,因此打印为不同的内容(在这里说德语;-))。然而,对于大多数 D-A-CH 书籍来说,这并不常见。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 2015-12-18
    • 1970-01-01
    • 2020-12-18
    相关资源
    最近更新 更多