У меня есть сущность Blog
, такая как:
@Entity
class Blog{
@Id
private Long id;
private String titie;
private String content;
@ManyToMany
@JoinTable(
name = "blog_tag_association",
joinColumns = @JoinColumn(name = "blog_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id")
)
private Set<Tag> tags = new LinkedHashSet<>();
// ...
}
Как вы можете видеть, я использую отдельную таблицу для представления отношений между Blog
и Tag
.
Я прочитал эту запись и написал свой собственный запрос JPQL, чтобы сопоставить мой результат запроса с DTO:
class BlogSummaryDTO{
private Long id;
private String title;
private Set<Tag> tags;
public BlogSummaryDTO(Long id, String title, Set<Tag> tags){
this.id = id;
this.title = title;
this.tags = tags;
}
}
И мой собственный JPQL вроде:
String query = "SELECT new com.okatu.rgan.blog.model.BlogSummaryDTO(" +
"b.id, b.title, " +
"b.tags) FROM Blog b";
Это не может работать, терминал сказал мне, что:
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax to use near 'as col_2_0_ from blog blog0_ inner join blog_tag_association tags1_ on blog0_.id' at line 1
sql, которое он генерирует, было похоже на:
Hibernate:
select
blog0_.id as col_0_0_,
blog0_.title as col_1_0_,
. as col_2_0_
from
blog blog0_
inner join
blog_tag_association tags1_
on blog0_.id=tags1_.blog_id
inner join
tag tag2_
on tags1_.tag_id=tag2_.id
where
blog0_.title like ?
or blog0_.title like ? limit ?
Если я удаляю свойство tags
из JPQL и DTO список параметров конструктора, он работает хорошо.
Так как мне написать свой собственный JPQL для создания DTO со свойством @JoinTable?
Я также наблюдал сгенерированный jpa sql когда BlogRepository::findById
использует отдельный нативный sql для извлечения Tag
.
Hibernate:
select
blog0_.id as id1_0_0_,
blog0_.content as content2_0_0_,
blog0_.created_time as created_3_0_0_,
blog0_.modified_time as modified4_0_0_,
blog0_.summary as summary5_0_0_,
blog0_.title as title6_0_0_,
blog0_.author_id as author_i9_0_0_,
user1_.id as id1_5_1_,
user1_.created_time as created_2_5_1_,
user1_.username as username7_5_1_,
from
blog blog0_
left outer join
user user1_
on blog0_.author_id=user1_.id
where
blog0_.id=?
Hibernate:
select
tags0_.blog_id as blog_id1_1_0_,
tags0_.tag_id as tag_id2_1_0_,
tag1_.id as id1_4_1_,
tag1_.description as descript2_4_1_,
tag1_.title as title3_4_1_
from
blog_tag_association tags0_
inner join
tag tag1_
on tags0_.tag_id=tag1_.id
where
tags0_.blog_id=?
Но я не знаю, какой JPQL он сгенерировал.