是否有可能有没有对象到对象映射执行外键?
-
22-09-2019 - |
题
假设下面的映射:
<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...
成<property...
这会工作,但外键不会被数据库中执行。
我需要这样做,因为对象B
可能(也可能不)被分开这有时导致初始化
当org.hibernate.LazyInitializationException: could not initialize proxy - no Session
被称为发生a.getB()
例外。我更愿意把它当作一个long idOfB
,每当需要加载整个对象;这也将使得对象A
更快的负荷。
我相信我的问题是非常相似的这个,但所提供的解决方案(使用延迟加载)没有在我的情况适合作为即使我打电话a.getB().getId()
,我会得到LazyInitializationException
而如果我打电话a.getIdOfB()
我不会。
非常感谢提前。
解决方案
如所述
我明白,如果我转换<多到一个...成<财产......这会工作,但是外键是不能强制执行按数据库。
所以我的建议是:同时使用
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属性插入=“假”。
的问候,
其他提示
您可以随时手动在Hibernate的hbm.xml文件中创建外键的DDL:
<hibernate-mapping>
...
<database-object>
<create>[CREATE FK]</create>
<drop>[DROP FK]</drop>
</database-object>
</hibernate-mapping>
您还可以得到支持范围这一点,如果不同的方言需要。
查核 5.7。辅助数据库对象
您可以采取另一种方法是用你的乙映射,而不是一个映射定义FK。我已经添加了JPA的代码,你必须,如果你不使用注释本翻译成你的Hibernate映射文件。
@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;
}
}
我建议你关联对象的对象得到休眠的全部优势。我认为这个问题是你得到的异常。这是因为当你试图让懒惰的对象Hibernate会话已经关闭。有在此博客的几个职位这表明回答这个问题,比如这个:链接文本。
如果你正在使用Spring,你可以使用OpenEntityManagerInViewFilter这样对话将保持打开,直到观点是renderes。