【问题标题】:Hibernate @Embeddable class which extends another @Embeddable class, Properties not found for @OneToMany mappingHibernate @Embeddable 类扩展了另一个 @Embeddable 类,未找到 @OneToMany 映射的属性
【发布时间】:2015-05-30 10:57:58
【问题描述】:

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

情况

有一个类被注释为@Embeddable(ParentPk.java),另一个类扩展了这个类@Embeddable(ChildPk.java),这个ChildPk.java用作SomeOwnerClass.java中的复合主键,它与另一个类@987654324有外部关系@ 并且倾向于使用属性 col1col2,它们在 ChildPk.java 的父类中可用,但是当执行查询时,hibernate 不会找到 col1col2 而不是如果我从父类复制 ChildPk.java 中的 col1col2 一切正常。

下面是SomeOwnerClass.java的代码sn-p,指的是col1col2

>  @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 在 SomeOwnerClass.java 中用作外键,则在 xml 映射中可访问,但在带注释的映射中不可用。

我无法更改班级的结构,因为它是旧版应用程序。

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>

【问题讨论】:

    标签: hibernate inheritance extends embeddable


    【解决方案1】:

    Hibernate 不支持@Embeddable 组件的继承:

    一个可嵌入对象不能直接被持久化或查询,它只能在其父对象的上下文中被持久化或查询。可嵌入对象没有 id 或表。 JPA 规范不支持具有继承的可嵌入对象,尽管一些 JPA 提供者可能允许这样做。

    ——Java_Persistence/Embeddables.

    JPA 规范不支持具有继承性的可嵌入对象
    所以你不能在@Embeddable中使用继承。

    您可以尝试通过将父 ID 作为子 ID 的属性来完成。

    【讨论】:

    • 感谢 saif 的回复,但相同的类关系在基于 xml 的配置中工作正常,我需要在注释中替代它。我添加了额外的细节“额外的细节”
    • +1 因为它是一个有效的答案,如果这意味着(通常)不应该有可用的注释
    • 这个答案完全不正确。正如我在下面对答案的评论中提到的,Hibernate 实际上“支持@Embeddable 的继承”。
    【解决方案2】:

    您可以在@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 测试)将在 Child 类中正确映射 parentPropertychildProperty

    【讨论】:

    • 这是正确的答案。 JPA 没有明确支持嵌入的继承。然而 Hibernate 确实支持嵌入的继承
    • 点击回车而不是上面的 shift+enter :( 这是正确的答案。JPA 没有明确支持嵌入的继承。但是 Hibernate 确实支持使用 @MappedSuperclass 定义其超级继承-type. IMO 我们应该添加对扩展另一个嵌入式的支持 - hibernate.atlassian.net/browse/HHH-12790
    • wilflfy 15 中的工作
    • 谢谢。通过这条指令,我在 JPA 生成的 PostgreSQL 数据库表中得到了从超类列映射的奇怪的“只读:没有对应的表列”DBeaver 信息。这是什么意思?
    猜你喜欢
    • 1970-01-01
    • 2020-05-06
    • 2010-10-31
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多