Reputation: 43
I want to have a Spring Boot @Query
in JpaRepository which returns me entities with a set of other entities. I know that I can use findAll()
method, and then take only those rows that I'm interested in, but I think that this is much slower. The problem is that my entity Booster
contains a Set
of other entities Boost
, and when i try to query it, I get an error. So, this is my Query
:
@Query( "select new app.model.Booster(" +
" B.id, " +
" B.active, " +
" B.games, " +
" B.ownerAccount, " +
" B.boosts, " +
" B.boosterNickname, " +
" B.additionalInformation) " +
"from " +
" Booster B " +
" left join Boost Bo on B.id = Bo.boostingAccount.id " +
"where " +
" B.games like %?1% " +
" and Bo.finished = true " +
"group by " +
" B.id")
List<Booster> findBoostersForOverview(String game);
These are my entity classes:
@Data
@Entity(name = "Booster")
public class Booster {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private boolean active;
private String games;
@OneToOne(mappedBy = "boosterAccount", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Account ownerAccount;
@OneToMany(mappedBy = "boostingAccount", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Boost> boosts;
private String boosterNickname;
private String additionalInformation;
@Data
@Entity(name = "Boost")
public class Boost {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id",nullable=false,unique=true)
private long id;
private Date dateCreated;
private Date dateFinished;
private Date dateLastModification;
private boolean finished;
private boolean paused;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "boosted_account_id", referencedColumnName = "id")
private Account boostedAccount;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "boosting_account_id", referencedColumnName = "id")
private Booster boostingAccount;
@OneToMany(mappedBy = "boost", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Game> games;
private String game;
private String additionalInformation;
private String server;
This is what console shows:
Hibernate:
select
booster0_.id as col_0_0_,
booster0_.active as col_1_0_,
booster0_.games as col_2_0_,
booster0_.id as col_3_0_,
. as col_4_0_,
booster0_.booster_nickname as col_5_0_,
booster0_.additional_information as col_6_0_
from
booster booster0_
//HERE IS SOME MORE LOGS THAT ARE UNNECESSARY HERE
And this is error i get:
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_4_0_, booster0_.booster_nickname as col_5_0_, booster0_.additional_info' at line 1
I know that I can query without Set
of Boost
, and then in another query get specific Boost
s, but in my app there will be a lot of SQL and my code will turn to spaghetti. Is there a simple way to solve my problem?
Upvotes: 2
Views: 152
Reputation: 8203
Can you add the following to your repository without any @Query
annotation and see?
List<Booster> findByGamesLikeAndBoostsFinishedIsTrue(String game);
Upvotes: 1
Reputation: 11580
The problem here, you are using GROUP BY
. When you are using Group By
you have use aggregate functions (COUNT, MAX, MIN, SUM, AVG)
to group the result-set by one or more columns in the select column. Aggregate functions are mandatory when using GROUP BY
function.
In your case, I hope Group By
is not required. Modify your code like below.
@Query( "select new app.model.Booster(" +
" B.id, " +
" B.active, " +
" B.games, " +
" B.ownerAccount, " +
" B.boosts, " +
" B.boosterNickname, " +
" B.additionalInformation) " +
"from " +
" Booster B " +
" left join Boost Bo on B.id = Bo.boostingAccount.id " +
"where " +
" B.games like %?1% " +
" and Bo.finished = true")
List<Booster> findBoostersForOverview(String game);
Upvotes: 0