В настоящее время я использую Eclipselink, но теперь я знаю, что большинство реализаций JPA довольно стандартизированы. Есть ли собственный способ сопоставить объект JPA с представлением? Я не собираюсь вставлять / обновлять, но вопрос в том, как обрабатывать аннотацию @Id. Каждая сущность в мире JPA должна иметь поле идентификатора, но многие из созданных мной представлений не соответствуют этому. Есть ли встроенная поддержка этого в JPA или мне нужно использовать хаки, чтобы заставить его работать? Я много искал и нашел очень мало информации об этом.
Поддерживает ли JPA сопоставление с представлениями sql?
Ответы (3)
Хотя использование аннотации @Id
с полями напрямую поддерживаемых типов - не единственный способ указать идентичность сущности (см. @IdClass
с несколькими аннотациями @Id
или @EmbeddedId
с @Embedded
), спецификация JPA требует первичного ключа для каждой сущности.
Тем не менее, вам не нужны сущности для использования JPA с представлениями базы данных. Поскольку сопоставление с представлением ничем не отличается от сопоставления с таблицей с точки зрения SQL, вы все равно можете использовать собственные запросы (createNativeQuery
на EntityManager
) для получения вместо них скалярных значений.
Я сам изучал это и нашел хак, который, я не уверен, работает на 100%, но выглядит многообещающим.
В моем случае у меня есть столбец FK в представлении, который может эффективно функционировать как PK - любой конкретный экземпляр этого постороннего объекта может появиться в представлении только один раз. Я определил два объекта из этого одного поля: один обозначен как ID и представляет необработанное значение поля, а другой предназначен только для чтения и представляет объект, на который идет ссылка.
@Id
@Column(name = "foreignid", unique = true, nullable = false)
public Long getForeignId() {
...
@OneToOne
@JoinColumn(name = "foreignid", insertable=false, updatable=false)
public ForeignObject getForeignObject() {
...
Как я уже сказал, я не уверен на 100% в этом (и я просто удалю этот ответ, если он окажется, что он не работает), но мой код прошел через определенную точку сбоя.
Не знаю, применимо ли это к вашей конкретной ситуации. И есть отличный шанс, что через 11 месяцев вам все равно. :-) Какого черта, значок "Некромант" не заработал сам ...
На мой взгляд, у меня есть «уникальный» идентификатор, поэтому я сопоставил его с идентификатором сущности. Работает очень хорошо:
@Entity
@Table(name="table")
@NamedQuery(name="Table.findAll", query="SELECT n FROM Table n")
public class Table implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="column_a")
private int columnA;