Я потратил 3 дня, пытаясь выяснить, как решить следующую проблему, но мне не удалось.
Моя проблема в том, что hibernate генерирует следующий запрос:
Hibernate: select distinct bankgroupe0_.id as col_0_0_, bankgroupe0_.name as col
_1_0_, bankentity1_.name as col_2_0_ from bank_groups bankgroupe0_ inner join banks bankentity1_ on
когда я выполняю запрос по методу findAllBankGroupTuples () из репозитория ниже.Кажется, что он не распознает отображение «многие ко многим» в соединении.Очевидно, что он завершается ошибкой, поскольку заканчивается ключевым словом «on», и не предоставляет условия соединения и не использует таблицу пересечений (BANK_GROUPS_MAPPINGS - DDL ниже).Тем не менее, я также могу найти следующий запрос в журнале (созданный из-за EAGER FetchType, который я поместил туда просто для проверки, работает ли он для других запросов, выполняемых без объединения):
Hibernate: select banks0_.group_id as group_id1_1_0_, banks0_.bank_id as bank_id2_1_0_, bankentity1_.id as id1_2_1_, bankentity1_.name as name4_2_1_ from bank_groups_mappings banks0_ inner join banks bankentity1_ on banks0_.bank_id=bankentity1_.id where banks0_.group_id=?
Так что я могуобратите внимание, что Hibernate может распознать это отношение «многие ко многим», когда в запросе нет соединения.Вышеуказанный запрос успешно выполнен.
Репозиторий:
public interface BankGroupRepository extends CrudRepository<BankGroupEntity, Long> {
@Query(value = "SELECT DISTINCT new com.api.entity.BankGroupTuple(bg.id, bg.name, b.name) FROM BankGroupEntity bg join BankEntity b")
List<BankGroupTuple> findAllBankGroupTuples();
}
BankGroupEntity:
@Entity
@Table(name="BANK_GROUPS")
public class BankGroupEntity implements Serializable {
@Id
@Column(name="ID")
private int id;
@Column(name="NAME")
private String name;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "BANK_GROUPS_MAPPINGS",
joinColumns = {@JoinColumn(name="GROUP_ID", referencedColumnName="ID")},
inverseJoinColumns = {@JoinColumn(name = "BANK_ID", referencedColumnName="ID")})
private List<BankEntity> banks;
BankGroupEntity() {
}
BankGroupEntity(String name) {
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<BankEntity> getBanks() {
return banks;
}
public void setBanks(List<BankEntity> banks) {
this.banks = banks;
}
}
BankEntity:
@Entity
@Table(name="BANKS")
public class BankEntity implements Serializable {
@Id
@Column(name = "ID", unique = true, nullable = false)
private int id;
@Column(name="NAME")
private String name;
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "banks")
private List<BankGroupEntity> bankGroups;
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<BankGroupEntity> getBankGroups() {
return bankGroups;
}
public void setBankGroups(List<BankGroupEntity> bankGroups) {
this.bankGroups = bankGroups;
}
}
База данных:
create table BANK_GROUPS
(
ID INTEGER not null
constraint BANK_GROUPS_ID_PK
primary key,
NAME VARCHAR(40) not null
);
create table BANKS
(
ID INTEGER
constraint BANKS_ID_PK
primary key,
NAME VARCHAR(40) not null
);
create table BANK_GROUPS_MAPPINGS
(
GROUP_ID INTEGER not null
references BANK_GROUPS,
BANK_ID INTEGER not null
references BANKS,
constraint BANK_GROUPS_MAPPINGS_PK
primary key (GROUP_ID, BANK_ID)
);
alter table BANK_GROUPS_MAPPINGS
add foreign key (GROUP_ID) references BANK_GROUPS;
alter table BANK_GROUPS_MAPPINGS
add foreign key (BANK_ID) references BANKS;
Настройки JPA:
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=validate
База данных, которую я использую - это DB2.
Подскажите, пожалуйста, что я делаю неправильно?Заранее спасибо
После предложения, что я не могу использовать конструктор с объединением, я изменил метод на следующий:
public interface BankGroupCrudRepository extends CrudRepository<BankGroupEntity, Long> {
@Query(value = "SELECT DISTINCT bg.id, bg.name, b.name FROM BankGroupEntity bg join BankEntity b")
List<Object[]> findAllBankGroupTuples();
}
И результат точно такой же - он завершает запросс "вкл"