๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring/Spring Data JPA

JPQL @Query ์—๋Ÿฌ: For queries with named parameters you need to use provide names for method parameters

by ์ฃผ๋ฐœ2 2021. 7. 6.
๋ฐ˜์‘ํ˜•

๐Ÿ“Ž For queries with named parameters you need to use provide names for method parameters

 

 

 

Spring Data JPA์—์„œ ์•„๋ž˜ Entity๋ฅผ ํ†ตํ•ด ์กฐํšŒ๋ฅผ ํ•˜๋ ค๋Š”๋ฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

(email์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋Š” DB์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.)

import ...

@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@ToString
public class ClubMember extends BaseEntity {

    @Id
    private String email;

    @Column
    private String password;

    @Column
    private String name;

    @Column
    private boolean fromSocial;

}


import ...

public interface ClubMemberRepository extends JpaRepository<ClubMember, String> {

    @Query("select m from ClubMember m where m.email = :email and m.fromSocial = :social")
    Optional<ClubMember> findByEmail(String email, boolean social);

}


    // ํ…Œ์ŠคํŠธ ์ฝ”๋“œ
    @Test
    void read_ClubMember() {
        /* given */
        String email = "user95@zerock.org";

        /* when */
        ClubMember clubMember = clubMemberRepository.findByEmail(email, false)
                .orElseThrow(NullPointerException::new);

        /* then */
        System.out.println(clubMember);
    }

Caused by: java.lang.IllegalStateException: For queries with named parameters you need to use provide names for method parameters. Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters.

 

 

 

์นœ์ ˆํ•˜๊ฒŒ๋„ ๋กœ๊ทธ์— ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters.

  • @Param ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ (Java 8+์—์„œ) -parameters ์„ ์‚ฌ์šฉํ•˜๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@Param: ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๋„ค์ž„์„ ํ†ตํ•ด ๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ฟผ๋ฆฌ์— ๋ฐ”์ธ๋“œ ์‹œํ‚ค๋Š” ์–ด๋…ธํ…Œ์ด์…˜

 

๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด @Param ์–ด๋…ธํ…Œ์ด์…˜์„ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ถ”๊ฐ€ํ•ด์„œ ํ•ด๊ฒฐ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

...

public interface ClubMemberRepository extends JpaRepository<ClubMember, String> {

    @Query("select m from ClubMember m where m.email = :email and m.fromSocial = :social")
    Optional<ClubMember> findByEmail(@Param("email") String email, @Param("social") boolean social);

}

 

 

 

๐Ÿค” ๊ทธ๋Ÿผ ๋‘ ๋ฒˆ์งธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ธ javac flag -parameters ๋Š” ๋ฌด์—‡์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฑธ๊นŒ์š”?

 

๋จผ์ € ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•๋ถ€ํ„ฐ ๋‚˜ํƒ€๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Preferences(Command + ,) > Build, Execution, Deployment > Compiler > Java Compiler

Additional command line parameters ๋ถ€๋ถ„์— -parameters ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

 

 

 

 

๐Ÿง ์ด์ œ -parameters ๋ผ๋Š”๊ฒŒ ๋ฌด์Šจ ์—ญํ• ์„ ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋จผ์ € Spring Data JPA ๊ณต์‹๋ฌธ์„œ ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜์™€์žˆ์Šต๋‹ˆ๋‹ค.

 

As of version 4, Spring fully supports Java 8’s parameter name discovery based on the -parameters compiler flag. By using this flag in your build as an alternative to debug information, you can omit the @Param annotation for named parameters.

 

(์˜์–ด๋ฅผ ์ž˜ ๋ชปํ•˜๊ธฐ์—๐Ÿ˜ญ) ๋Œ€๋žต -parameters compiler flag ๋ฅผ ํ†ตํ•ด @Param ์–ด๋…ธํ…Œ์ด์…˜์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

์—ด์‹ฌํžˆ ๊ตฌ๊ธ€๋ง์„ ํ•ด๋ณธ ๊ฒฐ๊ณผ .... stackoverflow ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธ€๋“ค์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

Q)

๋Œ€๋žต์ ์œผ๋กœ ํ•ด์„ํ•ด๋ณด๋ฉด ...

Custom JPQL @Query ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ , @Param ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ช…์‹œํ•˜์ง€ ์•Š์•˜๋Š”๋ฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. 

๋‚ด์šฉ์—๋Š” Java ๋ฒ„์ „์ด 8๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ, @Param ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ๋‚˜์™€์žˆ๋Š”๋ฐ ๋‚˜๋Š” Java 8์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ด๋ƒ? ๋ผ๊ณ  ์งˆ๋ฌธ์„ ๋‚จ๊ธฐ์…จ๊ณ ,

 

A)

Java 8์—์„œ ๋ฆฌํ”Œ๋ ‰์…˜์„ ํ†ตํ•ด ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ด๋ฆ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์ธํ•ด @Param ์–ด๋…ธํ…Œ์ด์…˜์ด ํ•„์š”ํ•˜์ง€ ์•Š๋Š”๋ฐ, ์Šคํ”„๋ง์ด ๋ฉ”์„œ๋“œ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์ด๋ฆ„์—์„œ

JPQL ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์ด๋ฆ„์„ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” -parameters flag ๋ฅผ ์ปดํŒŒ์ผ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

 

https://stackoverflow.com/questions/48515309/naming-query-parameters-in-spring-repository/48515494

 

 

๐Ÿง ๋”ฐ๋ผ์„œ ์œ„ ๋‚ด์šฉ๋“ค์„ ์š”์•ฝํ•ด๋ณด๋ฉด ...

 

Java 8๋ถ€ํ„ฐ -parameter flag ์„ค์ •์œผ๋กœ ๋ฉ”์†Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    @Query("select m from ClubMember m where m.email = :email and m.fromSocial = :social")
    Optional<ClubMember> findByEmail(@Param("email") String email, @Param("social") boolean social);

์ฆ‰, ์œ„ ์ฝ”๋“œ์—์„œ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ฟผ๋ฆฌ์— ๋ฐ”์ธ๋”ฉ ํ•  ๋•Œ, @Param ์–ด๋…ธํ…Œ์ด์…˜์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ธฐ๋ณธ์ ์œผ๋กœ Java์˜ .class ํŒŒ์ผ์€ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์ด๋ฆ„์„ ์ €์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์œ„ ์ฝ”๋“œ์—์„œ email, social)

ํŠน์ • .class ํŒŒ์ผ์— ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์„ ์ €์žฅํ•˜์—ฌ Reflection API๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ๊ฒ€์ƒ‰ํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด

javac compiler์˜ -parameters ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํŒŒ์ผ์„ ํ•ด์•ผ Runtime์‹œ์ ์— ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

๐Ÿ“ ์ถ”๊ฐ€ ์ž๋ฃŒ

-parameters, ๋ฆฌํ”Œ๋ ‰์…˜ ๋“ฑ์— ๋Œ€ํ•ด ์ถ”๊ฐ€์ ์ธ ์ž๋ฃŒ๊ฐ€ ์›ํ•˜์‹œ๋ฉด ์•„๋ž˜ ์‚ฌ์ดํŠธ๋“ค์„ ๋” ์ฝ์–ด๋ณด์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค :)

 

Named Parameters in Java 8

How to compile Java class to include method parameter names?

JEP 118: Access to Parameter Names at Runtime

Obtaining Names of Method Parameters

 

 

 

References

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€