Подтвердить что ты не робот

Hibernate - внешние ключи вместо объектов

В настоящее время 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

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

4b9b3361

Ответ 1

Да, вы можете это сделать. Вам просто нужно очистить для спящего режима, какой из них является отображением, которое он должен поддерживать, например:

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

Ответ 2

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

Ответ 3

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

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

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

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

  • Используйте объект сообщения напрямую, так как Hibernate будет загружать его только в случае, если необходимы данные, отличные от внешнего ключа. Не указывайте дополнительное поле для внешнего ключа.
  • Переключить класс для использования доступа к свойствам, т.е. определить геттеры и сеттеры и поместить аннотации из полей в получатели.

Ответ 4

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

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

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

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

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