У меня есть таблица, которая содержит 2 разных типа животных, которые я реализовал с помощью DescriminatorColumn.
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "OBJEKTTYP")
@Table(name = "ANIMAL")
public abstract class Animal extends {
@SequenceGenerator(name = "SEQ_ANIMAL", sequenceName = "SEQ_ANIMAL")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ANIMAL")
@Id
@Column(name = "ANIMAL_ID")
private Long id;
@Column(name = "NAME")
private String name;
@Column(name = "HOME_ID")
private Long homeId;
}
@Entity
@DiscriminatorValue("DOG")
public class Dog extends Animal {
@Column(name = "BARK")
private String bark;
}
@Entity
@DiscriminatorValue("CAT")
public class Catextends Animal {
@Column(name = "COLOR")
private String color;
}
У меня также есть другая сущность Home, которая содержит список кошек и список живых собак. в этом конкретном доме.
@Entity
@Table(name = "HOME")
public class Home {
@SequenceGenerator(name = "SEQ_HOME", sequenceName = "SEQ_HOME")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_HOME")
@Id
@Column(name = "HOME_ID")
private Long id;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
@JoinColumn(name = "HOME_ID")
private List<Cats> cats;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
@JoinColumn(name = "HOME_ID")
private List<Dogs> dogs;
//getters and setters
}
Теперь я сталкиваюсь с проблемой при попытке найти дом, в котором есть кошки, но нет собак:
entityManager.find(Home.class, 1L);
Сгенерированный SQL выглядит следующим образом :
SELECT * FROM HOME t0 LEFT OUTER JOIN ANIMAL t1 ON t0.HOME_ID = t1.HOME_ID WHERE (t1.OBJEKTTYP IS NULL OR t1.OBJEKTTYP IN ('DOGS')) ORDER BY t1.HOME_ID ASC;
В моем понимании, запрос просто неправильный, потому что он объединяет две таблицы и затем применяет условие. Я ожидаю, что запрос также даст результаты, если только кошки найдены для дома. Теперь запрос дает результаты, если либо Собаки были найдены, либо Животных вообще нет.
SQL, который я ожидаю, выглядел бы так:
SELECT * FROM HOME t0 LEFT OUTER JOIN ANIMAL t1 ON t0.HOME_ID = t1.HOME_ID AND (t1.OBJEKTTYP IN ('DOGS')) ORDER BY t1.HOME_ID ASC;
(обратите внимание на AND вместо ГДЕ)
SELECT * FROM HOME t0 LEFT OUTER JOIN (SELECT * FROM ANIMAL WHERE (OBJEKTTYP IN ('DOGS'))) t1 ON t0.PAF_ID = t1.PAF_ID ORDER BY t1.PAF_ID ASC;
Как изменить объявление Entity таким образом, чтобы сгенерированный SQL был правильным? (Обратите внимание, что установка FetchTypes на LAZY решает проблему, но, если возможно, я бы хотел избежать этого по другим причинам.)