Мы строим планировщик встреч. У нас много гостей, и каждый может посетить множество событий: сущности «Гость» и «Событие». Это много ко многим с промежуточной сущностью, которая называется "EventGuestRelation". Он имеет @EmbeddedId с двумя столбцами внешнего ключа Integer, который сохраняется хорошо, а встроенные методы JPArepository ведут себя нормально.
Проблема заключается в том, что я запрашиваю репозиторий EventGuestRelation.
Я не могу заставить программу вернуть мне EventGuestRelations, которые содержат определенное событие или определенного гостя. Просто ноль. Я показываю запросы на событие здесь для краткости.
Я пробовал
@Query("SELECT r.event FROM EventGuestRelation r WHERE r.event= :event")
public List<EventEntity> getEventIdsForEvent(@Param(value = "event") EventEntity event);
и
public List<EventGuestRelation> findByEvent(EventEntity event);
Оба производят SQL:
Hibernate:
select
evententit1_.id as id1_3_,
...
from
user_event_guest eventguest0_
inner join
eventlist evententit1_
on eventguest0_.event_sub=evententit1_.id
where
eventguest0_.event_sub=?
Правильный объект:
@Entity
@Table
public class EventEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
...
@OneToMany(mappedBy = "event" , cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
@JsonBackReference
private Set<EventGuestRelation> subscriptions = new HashSet<>();
...
Промежуточный субъект:
@Entity
@Table
public class EventGuestRelation {
@Embeddable
public static class EventGuestId implements Serializable {
@Column(name = "EVENT_ID")
protected Integer eventId;
...
}
@EmbeddedId
protected EventGuestId id = new EventGuestId();
@ManyToOne
@JoinColumn(name = "event_sub", insertable = false, updatable = false)
private EventEntity event;
...
Левая сущность (Гость) опущена.
Repository:
public interface EventGuestRepository extends JpaRepository<EventGuestRelation, EventGuestId> {
И части метода испытаний:
private final UserEntity ALYSSA = new UserEntity();
private final EventEntity GUESTING = new EventEntity();
private final EventGuestRelation AGUESTING = new EventGuestRelation();
userRepo.save(ALYSSA); // cascades to intemediate entity, checked;
AGUESTING.subscribe(ALYSSA, GUESTING); //bidirectional relation setter
List<EventEntity> eventsII = eventGuestRepo.getEventIdsForEvent(GUESTING);
assertEquals(eventsII.size(), 1); // fails
Я могу решить эту проблему неоптимальным образом:
Set<EventGuestRelation> subscriptions = ALYSSA.getSubscriptions();
Set<EventEntity> events = subscriptions.stream().map(s -> s.getEvent()).collect(Collectors.toSet())
но, очевидно, это не так элегантно, как запрос к базе данных напрямую.
Любая помощь будет высоко ценится.
Постскриптум Это та же Алисса из SICP.
Некоторые талисманы просто отказываются переходить в безвестность.