6

假设提供了以下映射:

<class name="A" table="a_table">
  <id name="id"/>
  <many-to-one name="entityB" column="fk_B" not-null="false" unique="true"/>
</class>

<class name="B" table="b_table">
  <id name="id"/>
</class>

Java类:

public class A {
   private long id;
   private B entityB;
   // getters and setters skipped
}

是否可以更改 Hibernate 映射,以便Hibernate 在启动时仍强制执行和创建外键,但类A如下所示:

public class A {
   private long id;
   private long idOfB;
   // getters and setters skipped
}

我知道,如果我转换<many-to-one...成 a<property...这会起作用,但数据库不会强制执行外键。

我需要这样做,因为对象B可能(或可能不会)单独初始化,这有时会导致 调用org.hibernate.LazyInitializationException: could not initialize proxy - no Session时发生异常。a.getB()我更愿意将它作为一个long idOfB并在必要时加载整个对象;这也将使对象的加载A更快。

我相信我的问题与这个问题非常相似,但是所提供的解决方案(使用延迟加载)在我的情况下并不合适,因为即使我打电话a.getB().getId(),我也会得到LazyInitializationException,而如果我打电话a.getIdOfB()我不会。

首先十分感谢。

4

4 回答 4

12

如前所述

我知道如果我将 <many-to-one... 转换为 <property... 这会起作用,但数据库不会强制执行外键

所以我的建议是:两者都用

public class EntityA {

    private Integer idOfB;

    private EntityB entityB;

    // getter's and setter's

}

<class name="A" table="a_table">
    <id name="id"/>
    <property name="idOfB" column="fk_B" not-null="false" unique="true"/>
    <many-to-one name="entityB" update="false" insert="false" column="fk_B"/>
</class>

请注意,当两个属性共享同一列时,您必须将有关它的设置放在一个属性中。否则,Hibernate 会报错。它解释了为什么我在 entityB 属性中定义 update="false" 和 insert="false"。

问候,

于 2010-01-26T03:09:22.090 回答
4

您始终可以在 hibernate hbm.xml 文件中手动创建外键 DDL:

<hibernate-mapping>
    ...
    <database-object>
        <create>[CREATE FK]</create>
        <drop>[DROP FK]</drop>
    </database-object> 
</hibernate-mapping>

如果需要支持不同的方言,您也可以对此进行限定。

查看5.7。辅助数据库对象

于 2010-01-25T17:57:36.353 回答
0

我建议您将对象关联到对象以充分利用 Hibernate。我认为问题是你得到的例外。这是因为当您尝试获取惰性对象时,Hibernate 会话已经关闭。这个博客中有几篇文章给出了这个问题的答案,例如这个:链接文本

如果您使用的是 spring,您可以使用 OpenEntityManagerInViewFilter 以便会话将保持打开状态,直到视图呈现。

于 2010-01-25T20:05:16.813 回答
0

您可以采取的另一种方法是使用 B 映射而不是 A 映射来定义 FK。我已经添加了 JPA 代码,如果您不使用注释,则必须将其转换为您的休眠映射文件。

@Entity
public class B
{
    private long id;
    private List<A> aList;

    @Id
    @Column( name = "ID" )
    public long getId()
    {
        return id;
    }

    @OneToMany
    @JoinColumn( name = "B_ID" )
    public List<A> getAList()
    {
        return aList;
    }
    public void setId( long id )
    {
        this.id = id;
    }
    public void setAList( List<A> aList )
    {
        this.aList = aList;
    }        
}

A.java 不会是这样的:

@Entity
public class A
{
    private long id;
    private long idOfB;

    @Id
    @Column( name = "ID" )
    public long getId()
    {
        return id;
    }
    @Column( name = "B_ID" )
    public long getIdOfB()
    {
        return idOfB;
    }
    public void setId( long id )
    {
        this.id = id;
    }
    public void setIdOfB( long idOfB )
    {
        this.idOfB = idOfB;
    }   
}
于 2010-01-25T18:14:52.510 回答