Как создать TypedQuery в JPQL, который запрашивает две таблицы, используя неявное соединение? - PullRequest
1 голос
/ 24 марта 2019

Я пытаюсь научиться использовать неявные объединения в JPQL. Пример, из которого я работаю, позволяет предположить, что можно ссылаться на внешний ключ как путь, а затем иметь доступ к атрибутам в таблице, на которые ссылается внешний ключ.

Это обязательное отношение 1: M между пользователем и отчетом. userId - это внешний ключ, который ссылается на пользователя.

Я проверил, что у меня импортированы правильные библиотеки, что у меня правильное отображение (@JoinColumn, @ManyToOne, @OneToMany, mappedBy и т. Д.), Все, кажется, в порядке.

@GET
@Path("findByTotalCalBurnedAndHeight/{height}/{totalCalBurned}")
@Produces({"application/json"})
public List<Report> findByTotalCalBurnedAndHeight(@PathParam("height") Integer height, @PathParam("totalCalBurned") Integer totalCalBurned) {
    TypedQuery<Report> q = em.createQuery("SELECT r FROM Report r WHERE r.totalCalBurned = :totalCalBurned AND r.userId.height = :height", Report.class);
    q.setParameter("height", height);
    q.setParameter("totalCalBurned", totalCalBurned);
    return q.getResultList();
}

Как видно выше, я пытаюсь получить доступ к атрибуту "height" в таблице "User" с помощью: r.UserId.height

Исходя из примера, с которым я работаю, я ожидаю, что здесь сработает объединение, однако в результате я получаю следующую ошибку: «Путь к полю состояния« r.userId.height »не может быть преобразован в действительный» типа. "

Я что-то здесь упускаю? Любые отзывы приветствуются.

Обновление для отображения сопоставления:

В классе отчета:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "REPORT_ID")
private Integer reportId;

@JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID")
@ManyToOne(optional = false)
@Basic(optional = false)
@NotNull
@Column(name = "USER_ID")
private Integer userId;

В классе пользователя:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "USER_ID")
private Integer userId;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")

@Basic(optional = false)
@NotNull
@Column(name = "HEIGHT")
private int height;

1 Ответ

1 голос
/ 24 марта 2019

Проблема в этой части:

r.userId.height

Чтобы это работало, userId должен быть сущностью. Вы можете определить отношение с полем user в Report и написать что-то вроде:

"SELECT r FROM Report r left join r.user u WHERE r.totalCalBurned = :totalCalBurned AND u.height = :height"

Изменить - изменить это:

@JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID")
@ManyToOne(optional = false)
@Basic(optional = false)
@NotNull
@Column(name = "USER_ID")
private Integer userId;

в:

@JoinColumn(name = "USER_ID")
@ManyToOne(optional = false)
@Basic(optional = false)
@NotNull
private User user;
...