JPA -Table列引用作为两个不同表的外键

时间:2018-04-11 15:29:37

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

亲爱的开发人员,您好

我目前的情况:我使用的是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),

1 个答案:

答案 0 :(得分:0)

我提出了这种映射方法:

@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..* <--> 0..* |Tax|

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

唯一剩下的是属性countryType,我可以将其关联为Book类型的属性,假设某本书未针对奥地利方言,因此印有不同的内容(在这里以德语发言;-))。然而,对于大多数D-A-CH书籍来说,这不是常规案例。

希望这有帮助。