Ответ 1
Да, вы можете это сделать. Вам просто нужно очистить для спящего режима, какой из них является отображением, которое он должен поддерживать, например:
@Column(name="message_key", updatable=false, insertable=false)
private Long message_fk;
В настоящее время 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
Есть ли лучший способ получить внешний ключ или это единственный?
Да, вы можете это сделать. Вам просто нужно очистить для спящего режима, какой из них является отображением, которое он должен поддерживать, например:
@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.
Однако с типом доступа на основе поля (например, в вашем случае, где аннотации размещаются в полях), возникает нерешенная проблема спящего режима: Hibernate загружает весь объект за прокси из базы данных. (http://blog.xebia.com/2009/06/13/jpa-implementation-patterns-field-access-vs-property-access/)
Мое конкретное предложение было бы (как, например, "правильный" ответ не работал в моем случае):
Long fk = entity1.getEntity2().getId();
Это должно сработать. Это не будет работать, если у вас есть составные первичные ключи, на которые ссылаются внешние ключи, но в этом случае ваше решение не будет работать. Учитывая мое решение, даже составной ключ не выглядел бы таким уродливым.
Long fkField1 = entity1.getEntity2().getCol1();
String fkField2 = entity1.getEntity2().getCol2();
Что-то вроде этого будет работать.
EDIT: Размышляя о вашем предлагаемом решении, он все равно не сработает, потому что Hibernate уже пытается автоматически создать поле FK для отношения Mapped, поэтому определение другого @Column просто попытается привязать ко второму столбцу с тем же именем.