是否可以在没有对象到对象映射的情况下强制执行外键?
假设提供了以下映射:是否可以在没有对象到对象映射的情况下强制执行外键?
<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
更快。
我相信我的问题是非常相似的this one,但所提供的解决方案(使用延迟加载)是不是在我的情况适合作为即使我打电话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属性中定义update =“false”和insert =“false”。
问候,
你总是可以在Hibernate的hbm.xml文件手动创建外键的DDL:
<hibernate-mapping>
...
<database-object>
<create>[CREATE FK]</create>
<drop>[DROP FK]</drop>
</database-object>
</hibernate-mapping>
你也可以此范围内,如果不同的方言需要得到支持。
另一个你可以采取的办法是与你的乙映射,而不是一个映射定义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的全部优势。我认为问题是你得到的例外。这是因为当您尝试获取惰性对象时,Hibernate会话已经关闭。在这个博客中有几个帖子显示了这个问题的答案,例如这个:link text。
如果您使用spring,可以使用OpenEntityManagerInViewFilter,这样会话将保持打开状态,直到视图呈现。
感谢您的回答,但我完全意识到为什么延迟加载异常会抛出以及如何处理它们。然而,这是一个特殊情况,我希望框架更加灵活并为我完成工作。因为这就是他们写作的原因,对吧?最后,我不认为我所要求的对于O-R映射框架来说太多了,不是吗? – mindas 2010-01-26 10:37:45
我强烈建议使用LazyLoading而不是重新发明轮子。你会得到类型安全的实体类,性能完全一样,并且可能会取消自定义重载代码。 请注意,如果使用不正确,LazyLoading只会导致LazyLoadingException,即在会话关闭后请求延迟加载。另请注意,请求对象的ID不会导致加载对象。我建议你发布一个关于LazyLoading具体问题的问题。 – meriton 2010-01-25 18:50:18
相信我,我确实使用LazyLoading。在我无法做到的情况下,这只是一个例子。否则我不会问。 – mindas 2010-01-26 10:26:49
相关问题:[java的 - 休眠 - 外键而不是实体](http://stackoverflow.com/questions/6311776/hibernate-foreign-keys-instead-of-entities)。 – 2016-10-14 10:53:27