万一Hibernateは、重複外部キーを処理することができますか?
-
26-09-2019 - |
質問
私は1つの列を共有する の両方の外部キーを持つ2つの異なるテーブルに2つの外部キーを持つテーブルを持っています
あなたが見ることができるように、COUNTRY_CODE(偶然referentiationパスの末尾に同じ列を参照)を共有する2つのFKSがあります。 あなたが見ることができるように私はCOUNTRYCODEプロパティと読み取り専用(挿入可能= falseの場合、更新可能な=偽)として、市内のCOUNTRY_CODEの@JoinColumnフラグ付き。 これは正直私にはかなり基本的に見えます。 「プロパティに挿入可能と非挿入可能の列が混在することは許されない」は、そのような弱い「言い訳」ではないのですか? 万一Hibernateは、例えば、これを処理することができますJPAの仕様に応じて?これはバグですか?CREATE TABLE ZipAreas
(
country_code CHAR(2) NOT NULL,
zip_code VARCHAR(10) NOT NULL,
state_code VARCHAR(5) NOT NULL,
city_name VARCHAR(100) NOT NULL,
PRIMARY KEY (country_code, zip_code, state_code, city_name),
FOREIGN KEY (country_code, zip_code) REFERENCES Zips (country_code, code),
FOREIGN KEY (country_code, state_code, city_name) REFERENCES Cities (country_code, state_code, name)
)
@Entity
@Table(name = "ZipAreas")
@IdClass(value = ZipAreaId.class)
public class ZipArea implements Serializable
{
@Id
@Column(name = "country_code", insertable = false, updatable = false)
private String countryCode;
@Id
@Column(name = "zip_code", insertable = false, updatable = false)
private String zipCode;
@Id
@Column(name = "state_code", insertable = false, updatable = false)
private String stateCode;
@Id
@Column(name = "city_name", insertable = false, updatable = false)
private String cityName;
@ManyToOne
@JoinColumns(value = {@JoinColumn(name = "country_code", referencedColumnName = "country_code"), @JoinColumn(name = "zip_code", referencedColumnName = "code")})
private Zip zip = null;
@ManyToOne
@JoinColumns(value = {@JoinColumn(name = "country_code", referencedColumnName = "country_code", insertable = false, updatable = false), @JoinColumn(name = "state_code", referencedColumnName = "state_code"), @JoinColumn(name = "city_name", referencedColumnName = "name")})
private City city = null;
...
}
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: geoinfo] Unable to configure EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:374)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
at tld.geoinfo.Main.main(Main.java:27)
Caused by: org.hibernate.AnnotationException: Mixing insertable and non insertable columns in a property is not allowed: tld.geoinfo.model.ZipAreacity
at org.hibernate.cfg.Ejb3Column.checkPropertyConsistency(Ejb3Column.java:563)
at org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:2703)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1600)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:796)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:707)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3977)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3931)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1368)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345)
at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1477)
at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1096)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:278)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:362)
... 4 more
他のヒント
方法は、検証バイパスにありますので、列は「@JoinColumnsOrFormulas」は、ソリューションを置くであることを示し、仕事にそれを得るます:
エラー:
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code"),
@JoinColumn(name = "zip_code", referencedColumnName = "code")})
private Zip zip = null;
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code", insertable = false, updatable = false),
@JoinColumn(name = "state_code", referencedColumnName = "state_code"),
@JoinColumn(name = "city_name", referencedColumnName = "name")})
private City city = null;
OKます:
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code"),
@JoinColumn(name = "zip_code", referencedColumnName = "code")})
private Zip zip = null;
@ManyToOne
@JoinColumnsOrFormulas(value = {
@JoinColumnOrFormula(formula = @JoinFormula(value = "country_code", referencedColumnName = "country_code")),
@JoinColumnOrFormula(column = @JoinColumn(name = "state_code", referencedColumnName = "state_code")),
@JoinColumnOrFormula(column = @JoinColumn(name = "city_name", referencedColumnName = "name"))
})
private City city = null;
よろしく、
私は、Hibernate 5を使用していますが、私はまだ、この例外を取得します。あなたは一つだけに挿入=「false」を、更新=「false」に追加した場合、あなたは混在挿入可能と非挿入可能の列こと、これが許可されていないことを知らせる例外が発生します。これは、トラッカーに既に存在する問題であるが、解決されていないようです。 Hibernateは、複数の重複する外部キーの
が使用するカラムにAnnotationExceptionをスロー私たちのケースでは、これは我々が実際には非常に簡単、あなたが主にpersistence.xmlを交換し、JPQLにHSQL(休止SQL)(JPA SQL)を書き換える必要があること与えられているEclipseLinkは、に移行することを意味しました。また、あなたは(EclipseがSessionCustomizerそれらを呼び出す)カスタム命名戦略を交換する必要があるかもしれません。もちろん、それはあなたが休止状態などの特別な機能を使用する場合は、休止状態等の検索しかし、我々の場合には、我々は移行が唯一の終わりに時間を取ったとき週間の外部キーの重複修正しようとしたとして行うことが難しいかもしれません。
このはまだ休止状態5で解決されていません。
私は@JoinColumnsOrFormulas
を使用している場合しかし、私はClassCastExceptionが取得します。
私の問題は、すべての結合列にinsertable = false, updatable = false
を解か追加:
例:
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code", insertable = false, updatable = false),
@JoinColumn(name = "state_code", referencedColumnName = "state_code", insertable = false, updatable = false),
@JoinColumn(name = "city_name", referencedColumnName = "name", insertable = false, updatable = false)})
private City city = null;