Привет, дорогие разработчики,
моя текущая ситуация: я использую 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),
Я придумал такой подход к сопоставлению:
@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'
}
Затем мы определяем два конкретных налоговых объекта, таких как:
@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
):
Определенная книга (та же книга) продается в разных странах, которые повышают разные ставки налогов. Поэтому я бы посоветовал изменить схему базы данных (структуры таблиц), если можно. Это приведет/приведет к: таблице m для сопоставления отношения
|Book| 0..* <--> 0..* |Tax|
правильно (в семантическом смысле). Сноска: Я надеюсь, что вы все еще находитесь на ранней стадии развития.
Остается только атрибут countryType
который я не могу назвать атрибутом типа Book
предполагая, что книга не изменена для австрийских диалектов и поэтому напечатана с другим контентом (говоря здесь как немецкий здесь ;-)). Однако для большинства книг DA-CH это не было обычным делом.
Надеюсь это поможет.