Java Hibernate-外键而不是实体

Java Hibernate-外键而不是实体,java,hibernate,mapping,foreign-keys,Java,Hibernate,Mapping,Foreign Keys,目前,Hibernate允许我使用直接加载由*-to-one关系定义的对象 entity1.getEntity2() 是否可以获取外键而不是对象 我看到的当前方法在我的映射中有额外的内容: @JoinColumn(name="message_key") @ManyToOne(targetEntity=Message.class,fetch=FetchType.LAZY) private Message message; //these lines currently exist @Colu

目前,Hibernate允许我使用直接加载由*-to-one关系定义的对象

entity1.getEntity2()
是否可以获取外键而不是对象

我看到的当前方法在我的映射中有额外的内容:

@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
是否有更好的方法获取外键,或者这是唯一的方法

Long fk = entity1.getEntity2().getId();
这应该行得通。只有当复合主键被引用为外键时,它才会起作用,但在这种情况下,您的解决方案也不会起作用。考虑到我的解决方案,即使是组合键也不会看起来那么难看

Long fkField1 = entity1.getEntity2().getCol1();
String fkField2 = entity1.getEntity2().getCol2();
像这样的东西会有用的

编辑:
进一步考虑您提出的解决方案,它无论如何都不会起作用,因为Hibernate已经尝试为映射关系自动创建FK字段,因此定义另一个@Column只需尝试绑定到具有相同名称的第二个列。

是的,您可以这样做。您只需要为hibernate弄清楚应该维护哪一个映射,如下所示:

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

如果您仍然希望引用实体,但不希望仅为了获取外键而从数据库加载实体,那么您的方法是正确的。将insertable和updateable=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;

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

外键不直接可见,但它当然是OneToMany关系“一”端对象的键

但是,对于基于字段的访问类型(例如,在您的示例中,注释放在字段上),存在一个未解决的hibernate问题:hibernate从数据库加载代理后面的整个对象。()

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

  • 直接使用message对象,因为Hibernate仅在需要非外键数据时才会加载它。不要为外键指定其他字段
  • 切换类以使用属性访问,即定义getter和setter,并将注释从字段放到getter

我不喜欢这个解决方案,因为它需要加载外键引用的实体。有办法避免吗?另外:@列将被视为一个单独的参数,而不是FK。至少我是这么认为的。关于@Column注释:请参考Affe的回答,了解我的意思,他的解释更清楚。关于实体被加载,您是对的,它会在您的懒惰获取类上造成加载。您的问题没有说明它试图避免获取,只是“如何获取FK值?”;实际上,如果您只是获取关联实体的id值,Hibernate不需要加载整个实体。在延迟加载中,它将已经从实体的映射表中的FK加载ID。如果entity1.entity2=Null,此代码将抛出NPE,并且如何指定此ID引用的实体?数据库架构应该包含真正的外键约束,这是无法从注释中识别的…建议在实体关系的正常完整映射之外进行此映射,如原始问题所示。当hibernate似乎混淆了哪一个是对象,哪一个是键时,我得到了一个classcastexception。任何“完全替代”消息实体本身的方法?看起来都不太好。考虑到大多数代码库对membersHow使用驼峰大小写,您是否知道“Hibernate仅在需要非外键数据时才会加载它”?你能提供一个参考资料吗?你也可以混合使用字段和属性访问。我只对id使用属性访问(由于bug),对其他人使用字段访问。另请参阅讨论—有人尝试过它,反之亦然,所以我只需要插入一个id,hibernate就可以正确地获取实体?@kaiser您能够基于id获取整个实体吗?