Hibernate - 外键而不是实体

时间:2011-06-10 20:35:06

标签: java hibernate mapping foreign-keys

目前,Hibernate允许我直接用

加载由* -to-one关系定义的对象
entity1.getEntity2()

是否可以获取外键而不是对象?

我看到的当前方法是对我的映射添加addint:

@JoinColumn(name="message_key")
@ManyToOne(targetEntity=Message.class,fetch=FetchType.LAZY)
private Message message;  //these lines currently exist

@Column(name="message_key")
private Long message_fk; //the idea is to add those 2 lines

是否有更好的方法来获取外键,或者这是唯一的方法?

4 个答案:

答案 0 :(得分:43)

是的,你可以这样做。你只需要明确hibernate哪个是它应该维护的映射,如下所示:

@Column(name="message_key", updatable=false, insertable=false)
private Long message_fk;

答案 1 :(得分:15)

如果您仍然希望引用您的实体但又不想从数据库加载它只是为了获取外键,那么您的方法是正确的。将insertable和updatabale = false添加到Column属性,以防止丢失对实体的正确引用。

@JoinColumn(name = "message_key")
@ManyToOne(targetEntity = Messages.class, fetch = FetchType.LAZY)
private Messages message;

@Column(name = "message_key", insertable = false, updatable = false)
private Long message_fk;

答案 2 :(得分:4)

实际上,如果FetchType为LAZY,则仅加载外键而不是消息对象是默认的Hibernate行为。这就是为什么在指定LAZY FetchType时要加载对象的代理。

外键不能直接显示,但它当然是OneToMany关系“一端”对象的关键。

但是,对于基于字段的访问类型(例如,在您的情况下,注释放在字段上),有一个未解决的休眠问题:Hibernate从数据库加载代理背后的整个对象。 (http://blog.xebia.com/2009/06/13/jpa-implementation-patterns-field-access-vs-property-access/

我的具体建议是(例如,“正确的”答案在我的案例中不起作用):

  • 直接使用消息对象,因为只有在需要非外键数据时,Hibernate才会加载它。不要为外键指定其他字段。
  • 切换课程以使用属性访问权限,即定义getter和setter,并将字段中的注释放入getter。

答案 3 :(得分:1)

Long fk = entity1.getEntity2().getId();

这应该有效。只有当复合主键被引用为外键时,它才会起作用,但在这种情况下,您的解决方案将无效。考虑到我的解决方案,即使是复合键看起来也不会那么难看。

Long fkField1 = entity1.getEntity2().getCol1();
String fkField2 = entity1.getEntity2().getCol2();

这样的事情会起作用。

修改 再考虑一下你提出的解决方案,它无论如何都行不通,因为Hibernate已经尝试为Mapped关系自动创建一个FK字段,所以定义另一个@Column只会尝试绑定到同名的第二列。