반응형

오류

QueryDSL적용중 QuerySyntaxException: {Entity} is not mapped 오류 발생
원인을 찾기 위해 이것 저것 찾아보고 별걸 다 해보다가 포기..
다음날 맑은 정신으로 보니 바로 보이는 문제점..

원인

결론부터 말하면 Multi Datasource구성 때문이였다

  • 쿼리를 만들 때 사용하는 JPAQueryFactory에서 EntityManager를 사용하는데 이때 기본으로 primary Datasource의 EntityManager를 사용한다.
    primary EntityManager에서  secondary의 entity 조회하는 요청을 받다보니 발생하던 오류였던것
    • gradle 설정부터 property 설정 repositoryImpl 다시 구현 등등.. 해봐도 해결이 안됨
    • secondary Datasource를 먼저 queryDSL로 변경하다보니 본인이 뭘 잘못 설정한게 아닐까 하는 생각으로 다른곳에서 원인을 찾고 있었다.

 

해결 방법

- Multi Datasource 구성에서는 datasource별로 다른 EntityManager를 사용하기 때문에
   각 datasource의 EntityManager로 JPAQueryFactory를 빈으로 등록

- RepositoryImpl.java에서도 올바른 JPAQueryFactory를 가져다가 사용 

QueryDslConfig.java

import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Configuration
public class QueryDslConfig {


    @PersistenceContext(unitName = "firstEntityManager")
    private EntityManager firstEntityManager;

    @PersistenceContext(unitName = "secondaryEntityManager")
    private EntityManager secondaryEntityManager;

    @Primary
    @Bean
    public JPAQueryFactory firstJpaQueryFactory() {
        return new JPAQueryFactory(firstEntityManager);
    }

    @Bean("secondaryJpaQueryFactory")
    @Qualifier("secondaryJpaQueryFactory")
    public JPAQueryFactory secondaryJpaQueryFactory() {
        return new JPAQueryFactory(thirdEntityManager);
    }

}

??RepositoryImpl.java

@Repository
public class ??RepositoryImpl implements ??Repository {

    private final JPAQueryFactory secondaryJpaQueryFactory;

    public ??RepositoryImpl(@Qualifier("secondaryJpaQueryFactory") JPAQueryFactory secondaryJpaQueryFactory) {
        this.secondaryJpaQueryFactory = secondaryJpaQueryFactory;
    }
...
}

 

build.gradle 설정

plugins {
...
	id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"

}

...

dependencies {
...
	implementation "com.querydsl:querydsl-jpa"
...
}
...
/*
 * queryDSL 설정 추가
 */
// queryDSL에서 사용할 경로 설정
def queryDlsDir = "$buildDir/generated/querydsl"

// queryDSL 설정 블록
// QueryDSL 설정 블록에서는 JPA 사용 여부와 QueryDSL 소스 코드를 생성할 디렉토리를 지정
// - jpa = true: JPA 엔터티를 기반으로 QueryDSL 클래스를 생성할 것임을 나타냄
// - querydslSourcesDir = querydslDir: QueryDSL 소스 코드를 저장할 디렉토리를 설정.
querydsl {
	jpa = true
	querydslSourcesDir = queryDlsDir
}
// SourceSet 설정: 소스셋에 QueryDSL 디렉토리를 추가하여 빌드 시 해당 디렉토리의 소스 코드가 컴파일되도록 함
sourceSets {
	main.java.srcDir queryDlsDir
}
// configurations 설정
// - compileOnly 구성에 annotationProcessor를 추가하여 annotation processor를 컴파일 시에만 사용하도록 설정
// - querydsl.extendsFrom compileClasspath: QueryDSL이 컴파일될 때 compileClasspath를 상속하도록 설정
//   이는 QueryDSL이 프로젝트 내의 다른 클래스 및 의존성을 참조할 수 있게 
configurations {
	querydsl.extendsFrom compileClasspath
}
// compileQuerydsl 설정
// - QueryDSL을 컴파일할 때 필요한 옵션을 설정
//   여기서는 annotationProcessorPath를 설정하여 QueryDSL의 annotation processor를 사용하도록 
compileQuerydsl {
	options.annotationProcessorPath = configurations.querydsl
}
반응형
반응형

마이그레이션 참고 문서

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide

 

GitHub - spring-projects/spring-boot: Spring Boot

Spring Boot. Contribute to spring-projects/spring-boot development by creating an account on GitHub.

github.com

 

Spring boot 3.0대로 올라가며 Java 17 버전을 베이스로 동작을 한다고 합니다.

그래서 project에 사용하는 Java 8.0과 Spring boot 2.3.*의 버전을 업그레이드를 진행하게 됐습니다.

이 글은 변경을 진행하며 발견한 이슈를 정리하는 글이며,, 계속해서 업데이트해갈 예정입니다...!
 * 2.3 ~ 3.0 사이에 변경된 내용들을 정리할 예정입니다.

 

업그레이드를 하기전 왜 많은 기업에서 8.0버전을 사용하는 이유를 짧게 찾아봤다.
다른 이유들도 많겠지만 LTS(Long Term Support)라 사용해왔다는 글들을 발견했다. 

17버전 부터는 8.0버전과 지원기간이 차이가 많이 나지 않고,
Spring boot 3.0이 17버전을 베이스로하기 때문에 업데이트를 진행하게 됐다..

Spring boot Version 변경 (Gradle)

더보기

build.gradle 설정 변경

...
plugins {
    id 'org.springframework.boot' version '3.0.0' // 3.0.0으로 변경
    ...
}
...

// Java version 변경
sourceCompatibility=17
targetCompatibility=17

assert System.properties["java.specification.version"] == "17"
...

gradle 버전업
gradle-wrapper.properties 설정 변경

distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip

 

 

1. properties에러

더보기

active profile 설정 방법이 2.4 버전부터 변경됨

https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4#profile-activation

  • profiles 설정 방법: spring.profiles에서 spring.config.on-profile로 변경됨
  • include 설정 방법: spring.profiles.include에서 spring.profile.group로 설정

 

서버 실행 명령어

java -jar -Dspring.profiles.active=dev {SPRING_PROJECT}.jar
  • 기존 application-dev.yml 설정
spring:
  profiles: dev
  profiles.include:
      - swagger
  • 변경
# application.yml
spring:
  profiles:
    group:
      dev: swagger,debug
      test: swagger
---
# application-dev.yml
spring:
  config:
    activate:
      on-profile: dev
  datasource:
    ...
---
# application-test.yml
spring:
  config:
    activate:
      on-profile: test
  datasource:
    ...
---
# application-prod.yml
spring:
  config:
    activate:
      on-profile: prod
  datasource:
    ...

 

2. cannot find javaee.*

더보기

spring boot 3.0부터는 javax.*이 대신 Jakarta EE 9 API()를 사용

 

javax를 jakarta로 변경해주기만 하면 됨

// 기존
import javax.servlet.??

// 변경
import jakarta.servlet.??

 

3. spring-security-without-the-websecurityconfigureradapter WebSecurityConfigurerAdapter Deprecated

더보기
In Spring Security 5.7.0-M2 we deprecated the WebSecurityConfigurerAdapter,
as we encourage users to move towards a component-based security configuration.

Spring Security 5.7.0-M2부터 WebSecurityConfigurerAdapter을 더이상 사용할 수 없음
자세한 해결 방법은 아래 링크 참조하면 되며 간단히 수정한 내용을 작성함

https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

 

1. WebSecurity config 설정 변경
WebSecurityCustomizerbean을 등록하는 것입니다.
* 5.8에서 변경된 내용 web.ignoring().antMatchers -> web.ignoring().requestMatchers

// 기존
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}

// 변경
@Bean
public WebSecurityCustomizer configure() throws Exception {
    // web.ignoring().antMatchers(HttpMethod, "")
	// -> web.ignoring().requestMatchers(HttpMethod, "")
    return (web) -> web.ignoring().requestMatchers(HttpMethod.OPTIONS, "/**");

}

2. HttpSecurity config 설정 변경  (수정필요)
SecurityFilterChainbean을 직접 등록하는 방식으로 변경
 * 5.5에서 변경된 내용 HttpSecurity.authorizeRequests() -> HttpSecurity.authorizeHttpRequests()

// 기존
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests((authorize) -> authorize
         // .antMatchers(ApiConstants.SAMPLE).hasAnyAuthority(AuthEnum.ADMIN.getName)
            .anyRequest().authenticated()
        )
        .httpBasic(withDefaults());
}

// 변경
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests((authorize) -> authorize
         // .requestMatchers(ApiConstants.SAMPLE).hasAnyAuthority(AuthEnum.ADMIN.getName)
            .anyRequest().authenticated()
        )
        .httpBasic(withDefaults());
    return http.build();
}

 

3. UrlAuthorizationConfigurer.AuthorizedUrl.access -> AuthorizeHttpRequestsConfigurer.AuthorizedUrl.access
attribute 문자열을 통해 권한을 부여하는 방식이 변경됨
access(String attribute) -> access(AuthorizationManager<RequestAuthorizationContext> manager)

API별 권한 부여방식이 변경됨
antMatchers -> requestMatchers

// 기존
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        ...
        .authorizeRequests()
        	.antMatchers("/api/v1").access("permitAll()")
        ...
 }
// 변경
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        ...
        .authorizeHttpRequests((authorize) ->
			authorize.requestMatchers("/api/v1")
				.access(new WebExpressionAuthorizationManager("permitAll()"))
        ...
	return http.build();
 }

 

4. Jasypt 오류 - auto configuration 설정방식 변경

더보기

properties 암호화로 사용하던 Jasypt가 동작을 안하는 오류가 발생했다..

 

원인은 3.0버전부터 auto-configuration 설정파일의 형식이 변경됐기 때문
기존: META-INF/spring.factories에 원하는 configuration 정의
변경: META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports에 정의

3.0에서 변경된 auto-configuration 등록 방법에 대응하기 위해선 라이브러리에 변경사항이 반영돼야 함

다음 이슈를 참고해 강제로 auto-configuration을 등록해 해결함
- https://github.com/ulisesbocchio/jasypt-spring-boot/issues/342

@ImportAutoConfiguration(classes = JasyptSpringBootAutoConfiguration.class) // Remove when Jasypt is released for spring boot 3 (or at least 2.7)
@SpringBootApplication
public class SampleApplication {
    ...
}

 

 

5. swagger-ui 404

더보기

Spring boot 3.0으로 마이그레이션하니 swagger-ui가 동작하지 않게됨
springfox git을 가보니 나만 그런게 아니라 안심이 됐다(?)

 

https://springdoc.org/

springdoc 공식 사이트에선 springdoc-openapi v2를 사용하면 3.0에서 사용 가능하다고하니
갈아탈 준비를 해야겠다..
우선 swagger-ui를 사용한 API doc 수정은 우선순위를 미루기로 결정


반응형
반응형

인텔리제이를 사용해 토이프로젝트를 개발하고있었는데
언제부턴가 각종 경고표시가 안나오고 있었다..

해결방법을 찾다가 못찾아 무시하고 사용하고 있었는데 우연히 해결방법을 찾았다!!!!!

우선 아래 코드를 보면

65번 라인에 @GetMappiong에는 노란색이 아닌 회색..ㅜㅜ

66번 라인에는 public String getError() 뒤에 thorws Exception이 있어야 하는데 아무런 경고가 나오지 않고있습니다.

에러가 분명 있는데 아무런 경고가 안나와 컴파일 도중에야 발견하곤 했는데 드디어 해결했네요 ㅎㅎ

 

  방법

 

 

1. 편집기 오른쪽 상단에 "OFF"가 적힌 버튼에 커서를 올린다.

 

 

2. 커서를 올리면 Highlight: None으로 돼있을건데 이걸 Syntax, All Problems중 선택

 

 

3. 완료

 

반응형

+ Recent posts