본문 바로가기

카테고리 없음

[JPA] Use @Param for query method parameters

Spring JPA에서 Named Parameters 를 사용할 때 아래와 같은 메시지의 예외가 발생하였다.

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.

위의 Spring Data Reference에 보아도 Named Parameters를 사용할 때 @Param를 사용하라고 적혀있다는 것이다. (6.3.6)

이상한 것은 전에는 @Param 없이도 잘 동작했는데 왜 그럴까?

 

일딴 그 예외를 발생시키는 주체는 ParameterBinder 안의 BasicQueryParameterSetterFactory 클래스였다. (getName 부분)

public class ParameterBinder {

	static final String PARAMETER_NEEDS_TO_BE_NAMED = "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.";

// in QueryParameterSetterFactory abstract class
private static class BasicQueryParameterSetterFactory extends QueryParameterSetterFactory {

	// ..
	@Nullable
	private JpaParameter findParameterForBinding(ParameterBinding binding) {

		JpaParameters bindableParameters = parameters.getBindableParameters();

		for (JpaParameter bindableParameter : bindableParameters) {
			if (binding.getRequiredName().equals(getName(bindableParameter))) {
				return bindableParameter;
			}
		}

		return null;
	}

	private Object getValue(JpaParametersParameterAccessor accessor, Parameter parameter) {
		return accessor.getValue(parameter);
	}

	private static String getName(JpaParameter p) {
		return p.getName().orElseThrow(() -> new IllegalStateException(ParameterBinder.PARAMETER_NEEDS_TO_BE_NAMED));
	}
}

하지만 여기는 예외를 발생시키는 부분이지 원인은 아니였다.

 

SingleEntityExecution 클래스

단일 엔티티 수행에 대한 것은 SingleEntityExecution 이 오버라이드하고 있다.

inner class 로 구현을 하고 있는데 JpaQueryExecution 안에 포함하고 있다.

public abstract class JpaQueryExecution {
	// ..
	static class SingleEntityExecution extends JpaQueryExecution {

		@Override
		protected Object doExecute(AbstractJpaQuery query, JpaParametersParameterAccessor accessor) {

			return query.createQuery(accessor).getSingleResult();
		}
	}
public abstract class static class comment
JpaQueryExecution PagedExecution  
  SingleEntityExecution return a single entity
  ModifyingExecution update, insert, delete
  DeleteExecution Since: 1.6
  ExistsExecution Since: 1.11
  ProcedureExecution Since: 1.6
  StreamExecution Since: 1.8

org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery#doCreateQuery

org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery#createBinder

org.springframework.data.jpa.repository.query.ParameterBinderFactory#createQueryAwareBinder