Hibernate – 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 @Column(name="message_key") private Long message_fk; //the idea is to add those 2 lines 

Есть ли лучший способ получить внешний ключ, или это единственный?

Да, вы можете это сделать. Вам просто нужно дать понять, что hibernate – это отображение, которое оно должно поддерживать, например:

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

Если вы все еще хотите ссылаться на свою сущность, но не хотите загружать ее из базы данных, чтобы получить внешний ключ, ваш подход правильный. Добавьте 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; 

На самом деле, по умолчанию для режима Hibernate загружается только внешний ключ вместо объекта сообщения, если FetchType LAZY. Вот почему есть прокси-серверы для объектов, которые будут загружены, когда вы укажете LAZY FetchType.

Внешний ключ не отображается напрямую, но он, конечно, является ключом объекта к «одному» концу отношений OneToMany.

Однако с типом доступа на основе поля (например, в вашем случае, где annotations размещаются в полях), возникает нерешенная проблема спящего режима: Hibernate загружает весь объект за прокси из базы данных. ( http://blog.xebia.com/2009/06/13/jpa-implementation-patterns-field-access-vs-property-access/ )

Мое конкретное предложение было бы (как, например, «правильный» ответ не работал в моем случае):

  • Используйте объект сообщения напрямую, так как Hibernate будет загружать его только в том случае, если необходимы данные, отличные от внешнего ключа. Не указывайте дополнительное поле для внешнего ключа.
  • Переключите class, чтобы использовать доступ к свойствам, то есть определить геттеры и сеттеры, и поместить свои annotations из полей в геттеры.
 Long fk = entity1.getEntity2().getId(); 

Это должно сработать. Это не будет работать, если у вас есть составные первичные ключи, на которые ссылаются foreign keys, но в этом случае ваше решение не будет работать. Учитывая мое решение, даже составной ключ не выглядел бы таким уродливым.

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

Что-то вроде этого будет работать.

EDIT: Думая о вашем предлагаемом решении больше, он все равно не сработает, потому что Hibernate уже пытается автоматически создать поле FK для отношения Mapped, поэтому определение другого @Column просто попытается привязать ко второму столбцу с тем же именем.

Давайте будем гением компьютера.