Hibernate – foreign keys вместо объектов
В настоящее время Hibernate позволяет загружать объекты, определенные отношениями «-to-one» напрямую с
entity1.getEntity2()
Возможно ли получить внешний ключ вместо объекта?
Текущий подход, который я вижу, добавляет к моему отображению:
- Нормализация MongoDB, внешний ключ и присоединение
- Oracle (ORA-02270): нет соответствующего уникального или первичного ключа для этой ошибки в столбце
- Свойство «Id» является частью ключевой информации объекта и не может быть изменено
- Внешний ключ MySQL InnoDB между различными базами данных
- Sql - косвенный внешний ключ
@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
Есть ли лучший способ получить внешний ключ, или это единственный?
- Как обрезать таблицу с ограниченным внешним ключом?
- Каков наилучший дизайн для таблицы базы данных, которая может принадлежать двум различным ресурсам и, следовательно, нуждается в двух разных внешних ключах?
- Хорошо ли иметь внешний ключ в качестве первичного ключа?
- Можно ли зафиксировать отношения от 0..1 до 0..1 в Entity Framework?
Да, вы можете это сделать. Вам просто нужно дать понять, что 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 просто попытается привязать ко второму столбцу с тем же именем.