Репозиторий JPA / SpringBoot для представления базы данных (не таблицы) - PullRequest
0 голосов
/ 28 ноября 2018

Я пытаюсь создать объект JPA для представления.На уровне базы данных таблица и представление должны быть одинаковыми.

Однако проблемы начинают возникать, и они имеют две стороны:

  1. При попытке настроитьправильные аннотации.Представление не имеет первичного ключа, связанного с ним, но без надлежащих @javax.persistence.Id, аннотированных на поле, вы получите org.hibernate.AnnotationException: No identifier specified for entity, брошенный во время выполнения.

  2. Spring BootДля определения интерфейса JpaRepository требуется, чтобы тип ID расширял Serializable, что исключает использование java.lang.Void в качестве обходного пути из-за отсутствия идентификатора в объекте представления.

Каков правильный способ взаимодействия JPA / SpringBoot / Hibernate с представлением, в котором отсутствует первичный ключ?

Ответы [ 4 ]

0 голосов
/ 28 ноября 2018

Если в вашем представлении нет ключа-кандидата, вы можете добавить его в запросе на создание, используя что-то вроде функции UUID базы данных, а затем использовать UUID в качестве типа для идентификатора объекта.

Если выЕсли ваша сущность доступна только для чтения, вы можете аннотировать поля с помощью

 @Column(insertable = false, updatable = false)

или аннотировать свой класс сущности с помощью org.hibernate.annotations.Imutable, если ваш провайдер - Hibernate> = 5.2.

0 голосов
/ 28 ноября 2018

Надеюсь, это поможет вам. Идентификатор, которому вы можете присвоить его объединенному значению в вашем представлении.

Мы сопоставляем представление с объектом JPA следующим образом:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;

@Entity
@Table(name = "my_view")
public class MyView implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "my_view_id")
private Long myViewId;
@NotNull
@Column(name = "my_view_name")
private String myViewName;
}

Затем мысоздать хранилище:

import org.springframework.data.jpa.repository.JpaRepository;

public interface MyViewRepository extends JpaRepository<View, Long> {
}
0 голосов
/ 28 ноября 2018

Я тоже изучал эту тему.В итоге я использовал Spring Data JPA Проекции на основе интерфейса с собственными запросами.

Я создал интерфейс, убедившись, что часть UPPERCASE соответствует именам столбцов БД:

public interface R11Dto {

   String getTITLE();

   Integer getAMOUNT();

   LocalDate getDATE_CREATED();
}

Затем я создал хранилище для сущности (пользователя), никак не связанной сПосмотреть.В этом хранилище я создал простой нативный запрос.vReport1_1 мой взгляд.

public interface RaportRepository extends JpaRepository<User, Long> {

   @Query(nativeQuery = true, value = "SELECT * FROM vReport1_1 ORDER BY DATE_CREATED, AMOUNT")
   List<R11Dto> getR11();

}
0 голосов
/ 28 ноября 2018

Об отображении идентификатора объекта

Если вы можете изменить определение представления, вы можете использовать добавление rownum в качестве столбца.
Обычно оно относится к СУБД.Идея состоит в том, чтобы сделать номер строки в таблице идентификатором сущности.
В качестве альтернативы вы можете использовать генератор уникального идентификатора.UUID возможно.Наконец, вы можете придерживаться нативного SQL, используя JPA / Hibernate, чтобы отобразить нативные результаты запроса в определенный класс, представляющий данные представления.

О репозитории данных Spring

Если представления не вписываются естественным образом в требования к репозиторию данных Spring, это, вероятно, означает, что использование представлений вместо таблиц необязательно подходит для,

Действительно, классы репозиториев Spring Data, такие как CrudRepository или JpaRepository, предназначены для обеспечения готовых операций CRUD и некоторой дополнительной обработки для конкретного класса сущностей.
Представления в терминах СУБДне включается в выбранный вами, но вы не обновляете, не вставляете и не удаляете напрямую ни одну строку из представления.
Кроме того, что будет дополнительным преимуществом для использования таких компонентов репозитория для представления?Вы почти не будете использовать сгенерированную реализацию, предоставленную Spring.

В вашем случае, если вы определите представление как сущность, я думаю, что использование JpaTemplate будет иметь больше смысла.
Это просто слой поверх API JPA.
От документация :

JpaTemplate можно рассматривать как прямую альтернативу работе с нативным API-интерфейсом EntityManager JPA (с помощью общей ссылки EntityManager, как описано выше).Основным преимуществом является его автоматическое преобразование в DataAccessExceptions;основным недостатком является то, что он вводит еще один тонкий слой поверх нативного API JPA.Обратите внимание, что преобразование исключений также может быть достигнуто с помощью AOP;проверить PersistenceExceptionTranslationPostProcessor

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