我花了3天的时间进行调查,试图找出解决以下问题的方法,但失败了。
我的问题是休眠状态会生成以下查询:
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。
您能告诉我我做错了什么吗?预先感谢
在建议不能将构造函数与join一起使用后,我将方法更改为以下内容:
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();
}
结果完全相同-它产生以“ on”结尾的查询