web-dev-qa-db-ja.com

別の@Embeddableクラスを拡張するHibernate @Embeddableクラス、@ OneToManyマッピングのプロパティが見つかりません

古いxmlベースの構成をアノテーションベースの構成に変換しています

状況

@Embeddable(ParentPk.Java)と注釈が付けられたクラスがあり、別のクラスが@Embeddable(ChildPk.Java)であるこのクラスを拡張し、このChildPk.JavaがSomeOwnerClass.Javaの複合主キーとして使用されています。別のクラスSomeChildTable.Javaとの外部関係であり、ChildPk.Javaの親クラスで使用できるプロパティcol1およびcol2を使用する傾向がありますが、クエリが実行されると休止状態になります親クラスからChildPk.Javaの-​​col1およびcol2をコピーした場合、むしろcol1およびcol2が見つかりませんすべてがうまくいきます。

以下はcol1およびcol2を参照するSomeOwnerClass.Javaのコードスニペットです。

>  @OneToMany(orphanRemoval = true, fetch=FetchType.EAGER)
>        @Cascade(value = {CascadeType.ALL,CascadeType.SAVE_UPDATE})
>        @Fetch(FetchMode.JOIN)
>        @JoinColumns({
>        @JoinColumn(name="COL_1",insertable=false,updatable=false,referencedColumnName="COL_1"),
>        @JoinColumn(name="COL_2",insertable=false,updatable=false,referencedColumnName="COL_2"),
>        @JoinColumn(name="COL_3",insertable=false,updatable=false,referencedColumnName="COL_3"),
>     })    private Set<SomeChildTable> collection = new
> HashSet<SomeChildTable>();

この状況の解決策はありますか?

ParentPk.Java

 @Embeddable
    public class ParentPk implements Serializable  {

        @Column(name="COL_1")
        private String col1;

        @Column(ame="COL_2")
        private String col2;

    }

ChildPk.Java

@Embeddable
public class ChildPk extends ParentPk implements Serializable  {

    @Column(name="COL_3")
    private String col3;
}

SomeOwnerClass.Java

@Entity
@Table(name="FOO")
public class SomeOwnerClass implements Serializable  {

    @EmbeddedId
       @AttributeOverrides({@AttributeOverride(name="col1", column=@Column(name="COL_1",length=38))})
        private ChildPk childPk = new ChildPk();

         @OneToMany(orphanRemoval = true, fetch=FetchType.EAGER)
         @Cascade(value = {CascadeType.ALL,CascadeType.SAVE_UPDATE})
         @Fetch(FetchMode.JOIN)
         @JoinColumns({
         @JoinColumn(name="COL_1",insertable=false,updatable=false,referencedColumnName="COL_1"),
         @JoinColumn(name="COL_2",insertable=false,updatable=false,referencedColumnName="COL_2"),
         @JoinColumn(name="COL_3",insertable=false,updatable=false,referencedColumnName="COL_3"),
      })
    private Set<SomeChildTable> collection = new HashSet<SomeChildTable>();
}

例外

org.hibernate.MappingException: Unable to find column with logical name: COL_1 in SomeOwnerClass
    at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.Java:587)
    at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.Java:258)
    at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.Java:1451)
    at org.hibernate.cfg.annotations.CollectionBinder.bindOneToManySecondPass(CollectionBinder.Java:864)
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.Java:779)
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.Java:728)
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.Java:70)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.Java:1695)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.Java:1424)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.Java:1844)
    at com.foo.mypackage.ParentHibernateUtil.initiateSessionFactory(ParentHibernateUtil.Java:112)
    at com.foo.mypackage.ParentHibernateUtil.getSessionFactory(ParentHibernateUtil.Java:131)
    at com.foo.mypackage.GenericHibernateDAO.getSession(GenericHibernateDAO.Java:36)
    at com.foo.mypackage.GenericHibernateDAO.beginTransaction(GenericHibernateDAO.Java:63)
    at com.foo.mypackage.MarsTest.main(MyTest.Java:22)

追加の詳細 xmlベースの構成を注釈ベースの構成にマップしようとしましたが、継承の点で正常に機能する古いxmlベースの構成です。

ChildPk.Javaは、ParentPk.Javaを拡張する@Embedableに変換されます

<class name="SomeOwnerClassDetail" table="FOO_DETAIL">

        <composite-id class="ChildPk"
            name="childPk">
            <key-property name="col1" column="COL_1"  type="Java.lang.Long"/>
            <key-property name="col2" column="COL_2" length="32"/>
            <key-property name="col3" column="COL_3" length="3"/>
        </composite-id>
    </class>

上記のマッピングで、col1とcol2はParentPk.Javaから継承されます。ChildPkがXMLマッピングでSomeOwnerClass.Javaの外部キーとして使用されているが、注釈付きマッピングでは使用されていない場合にアクセスできます。

レガシーアプリケーションなので、クラスの構造を変更できません。

SomeOwnerClass.Java

<set name="someDetailKey" cascade="all,delete-Orphan,save-update" lazy="false" fetch="join"  > 
        <key foreign-key="FOO_Foreign_Key" >
            <column name="COL_1"/>
            <column name="COL_2"/>
            <column name="COL_3"/>
        </key>
        <one-to-many class="ChildPk" />
    </set>
17
Yahya Arshad

@Embeddableクラス間の継承を実装できます。親クラスにも@MappedSuperclassで注釈を付けるだけです。

したがって、例:

@Embeddable
@MappedSuperclass
public class Parent {
    @Basic
    private String parentProperty;

    // ... getters/setters
}

@Embeddable
public class Child extends Parent {
    @Basic
    private String childProperty;

    // ... getters/setters
}

このようにして、Hibernate(5.xでテスト済み)はparentPropertyクラスでchildPropertyChildの両方を正しくマップします。

31
mihu86

Hibernateは@Embeddableコンポーネントの継承をサポートしていません:

埋め込み可能なオブジェクトは直接永続化またはクエリすることはできません。永続化またはクエリできるのは、その親のコンテキストでのみです。埋め込み可能なオブジェクトにはIDまたはテーブルがありません。 JPA仕様では、継承を持つ埋め込み可能なオブジェクトをサポートしていませんが、一部のJPAプロバイダーでは継承が許可されています。

Java_Persistence/Embeddables

JPA仕様は、継承を持つ埋め込み可能オブジェクトをサポートしていません
したがって、@Embeddableで継承を利用することはできません。

親IDを子IDのプロパティとして持つことで、それを実現することができます。

11
Saif