3

私はレガシーデータベースを持っています。

+----+  +------------+ +------------+
|Site|  |Content     | |Program     |
+----+  +------------+ +------------+
|id  |  |id:PK       | |siteId:PK,FK|
|name|  |siteId:FK   | |code:PK     |
+----+  |prog_code:FK| |name        |
        |prog_param  | +------------+
        +------------+  

テーブル コンテンツには 1 つの PK 列があります。siteId 列は PK の一部ではありません。Table Program には 2 つの PK 列 (siteId、code) があります。複合PKです。このテーブルはテンプレートとして機能します。プログラム内の変数のみがパラメーターであり、それはテーブル Content の prog_param 列にあります。

このテーブルをこのようなオブジェクトにマップしたい。

+-----------+  +------------+  +-----------+  +---------------+
|Site       |  |Program     |  |ProgramId  |  |Content        |
+-----------+  +------------+  +-----------+  +---------------+
|id:long    |  |id:ProgramId|  |site:Site  |  |id:long        |
|name:String|  |name:String |  |code:String|  |site:Site      |
+-----------+  |param:String|  +-----------+  |program:Program|
               +------------+                 +---------------+

しかし、この複雑な状況で「コンテンツ」と「プログラム」をマッピングする方法がわかりません。

だから、私は状況を単純化しようとしました。prog_param を Content にマップしました

+-----------+  +------------+  +-----------+  +-------------------+
|Site       |  |Program     |  |ProgramId  |  |Content            |
+-----------+  +------------+  +-----------+  +-------------------+
|id:long    |  |id:ProgramId|  |site:Site  |  |id:long            |
|name:String|  |name:String |  |code:String|  |site:Site          |
+-----------+  +------------+  +-----------+  |program:Program    |
                                              |programParam:String|
                                              +-------------------+

コードとして

@Entity
@Table(name = "SITE")
@Getter @Setter
public class Site {
    @Id
    @Column(name = "SITE")
    protected String id;

    @Column(name = "NAME")
    protected String name;
}


@Entity
@Table(name = "PROGRAM")
@Getter @Setter
public class Program {
    @EmbeddedId
    protected ProgramId id;
    @Column(name = "NAME")
    protected String name;
}

@Embeddable
@Getter @Setter @EqualsAndHashCode
public class ProgramId implements Serializable{
    @ManyToOne
    @JoinColumn(name = "SITE")
    protected Site site;

    @Column(name = "code")
    protected String code;
}

@Entity
@Table(name="CONTENT")
@Getter
@Setter
public class Content {
    @Id
    @Column(name = "ID")
    protected Long id;

    @ManyToOne
    @JoinColumn(name = "SITEID",referencedColumnName="SITE")
    protected Site site;


    @OneToOne
    @JoinColumns({
        @JoinColumn(name="SITEID",referencedColumnName="SITE"),
        @JoinColumn(name="PROG_CODE",referencedColumnName="CODE"), 
    })
    protected Program program;
}

しかし、これは仕事ではありません。Hibernate が「エンティティのマッピングで列が繰り返されました」という例外をスローします。

だから私はいくつかの解決策を研究しています。最後に、この「エンティティのマッピングで繰り返される列」例外がスローされるのを見つけました。これは、Hibernate がどのプロパティを使用するかを判断できない場合です。

Stackoverflows の解決策は、@JoinColumn に 'insertable=false, updatable=false' を設定することで、hibernate がどのプロパティを使用するかを決定できるようにします。

非常に頻繁に使用されるので、コンテンツのプロパティ「サイト」を使用したい。そして、サイトとプログラムのプロパティは、私のアプリケーションでは別々に使用されます。

だから私はコンテンツのプロパティ「プログラム」に「挿入可能=偽、更新可能=偽」を設定しようとします

    @OneToOne
    @JoinColumns({
        @JoinColumn(name="SITEID",referencedColumnName="SITE", insertable=false, updatable=false),
        @JoinColumn(name="PROG_CODE",referencedColumnName="CODE"), 
    })
    protected Program program;

これも仕事ではありません。「プロパティに更新可能な列と更新できない列を混在させることはできません」という例外がスローされます。

したがって、'insertable=false, updatable=false' を 'PROG_CODE' に設定しました。もちろん、別の prog_code を設定しても、Hibernate は PROG_CODE を変更しません。

この時点で、私にはわかりません。

この状況を解決するためのアイデアを教えてください。

4

1 に答える 1

1

私は同じ問題を抱えています。属性を共有する2つの複合キーは、「エンティティのマッピングで列が繰り返されます」で失敗します。これはバグかもしれないと思います。参照: https://hibernate.atlassian.net/browse/HHH-4582。休止状態 3.6.4 を使用しています

于 2013-09-02T14:42:57.360 に答える