Hibernate @Embeddable类扩展了另一个@Embeddable类,找不到@OneToMany映射的属性 [英] Hibernate @Embeddable class which extends another @Embeddable class, Properties not found for @OneToMany mapping

查看:121
本文介绍了Hibernate @Embeddable类扩展了另一个@Embeddable类,找不到@OneToMany映射的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在将基于xml的旧配置转换为基于Annotation的配置

情况

有一个类被注释为 @Embeddable(ParentPk.java),另一个类扩展了这个类,它是 @Embeddable(ChildPk.java ),这个ChildPk.java被用作 SomeOwnerClass.java 中的复合主键,它与另一个类 SomeChildTable.java 并倾向于使用父类 ChildPk.java 中的 col1 col2 code>但是当执行查询时,hibernate没有找到 col1 col2 ,而是如果我复制 col1 col2 在父类中的 ChildPk.java 中,每一件事都可以正常工作。



以下是 SomeOwnerClass.java 的代码片段,它指 col1 col2

 > @OneToMany(orphanRemoval = true,fetch = FetchType.EAGER)
> @Cascade(value = {CascadeType.ALL,CascadeType.SAVE_UPDATE})
> @Fetch(FetchMode.JOIN)
> @JoinColumn({
> @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 
公共类ParentPk实现Serializable {

@Column(name =COL_1)
private String col1;

@Column(ame =COL_2)
private String col2;




ChildPk.java p>

  @Embeddable 
public class ChildPk extends ParentPk implements Serializable {

@Column(name = COL_3)
私人字符串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:无法在org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn。)中的SomeOwnerClass 
中查找具有逻辑名称:COL_1的列。
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)
位于org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70)
位于org.hibernate.cfg。 Configuration.originalSecondPassCompile(Configuration.ja va:1695)
在org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424)
在org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
在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转换为@Embedable,它扩展了ParentPk.java

 < class name =Som eOwnerClassDetailtable =FOO_DETAIL> 

< composite-id class =ChildPk
name =childPk>
< key-property name =col1column =COL_1type =java.lang.Long/>
< key-property name =col2column =COL_2length =32/>
< key-property name =col3column =COL_3length =3/>
< / composite-id>
< / class>上面的映射col1和col2中的

是从ParentPk.java继承的,如果ChildPk用作外键在xml映射中键入SomeOwnerClass.java,但不在注释映射中。



我无法更改我的类的结构,因为它是传统应用程序。 b
$ b

SomeOwnerClass.java



 < set name =someDetailKeycascade =all,delete-orphan,save-updatelazy =falsefetch =join> 
< key foreign-key =FOO_Foreign_Key>
< column name =COL_1/>
< column name =COL_2/>
< column name =COL_3/>
< / key>
< / set>


解决方案

您可以在 @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 childProperty > Child class。


We are translating old xml based configuration to Annotation based configuration

Situation

There is a class which is annotated as @Embeddable(ParentPk.java), another class extends this class which is @Embeddable(ChildPk.java), this ChildPk.java is used as composite primary key in SomeOwnerClass.java, Which have foreign relation with another class SomeChildTable.java and tends to use properties col1 and col2 which are available in parent class of ChildPk.java but when query is executed hibernate does not finds col1 and col2 rather if I copy col1 and col2 in ChildPk.java from parent class every thing works fine.

Below is code snippet of SomeOwnerClass.java which refers to col1 and col2

>  @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>();

Any solution for this situation?

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>();
}

Exception

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)

Additional Detail I have tried to map xml based configuration to annotation based configuration below is old xml based configuration which works fine in term of inheritence.

ChildPk.java converted to @Embedable which extends ParentPk.java

<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>

in above mapping col1 and col2 are inherited from ParentPk.java which are accessible if ChildPk is used as foreign key in SomeOwnerClass.java in xml mapping but not in annotated mapping.

I can't change structure of my class as it is legacy application.

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>

解决方案

You can implement inheritance between @Embeddable classes. You just have to annotate the parent class with @MappedSuperclass too.

So, e.g.:

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

    // ... getters/setters
}

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

    // ... getters/setters
}

This way Hibernate (tested with 5.x) will map both parentProperty and childProperty correctly in the Child class.

这篇关于Hibernate @Embeddable类扩展了另一个@Embeddable类,找不到@OneToMany映射的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆