package com.calmlog.api.config;

import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.function.Supplier;

@Configuration
public class QueryDslConfig {
    @PersistenceContext
    public EntityManager em;

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(em);
    }
}

QueryDsl에 관한 설정을 하는 클래스를 만들고 JPAQueryFactory 빈을 생성하기 위해 코드를 작성했는데

생성자에 EntityManager 객체를 넣어줬는데 인수로 받지 못하는 경우가 발생했다.

그래서 생성자에 필요한 EntityManager의 타입을 살펴보니

javax.persistence.EntityManager 를 필요로 한다는 것을 알게되었다.

 

ChatGPT에 패키지가 다른(jakarta, javax) 두 클래스의 차이가 무엇인지 검색해보았다.

더보기

jakarta.persistence.EntityManager와 javax.persistence.EntityManager는 Java Persistence API (JPA)의 일부분으로서 엔터티 매니저를 나타내는 두 가지 인터페이스입니다.

  1. javax.persistence.EntityManager: 이 인터페이스는 Java EE 5 및 Java SE 6에서 처음 도입되었습니다. Java EE 5에서 JPA는 javax.persistence 패키지 아래에 정의되었습니다. 그러나 Java EE와 관련된 기술 키워드가 Java EE의 이후 버전에서 문제가 되기 시작하면서 표준을 지속하기 위해 jakarta로 패키지 이름이 변경되었습니다. 그 결과, Java EE 8 이후의 버전에서는 javax.persistence를 사용하는 것보다 jakarta.persistence를 사용하는 것이 권장됩니다.
  2. jakarta.persistence.EntityManager: 이 인터페이스는 Jakarta EE 8에서 등장한 패키지 이름 변경에 따른 새로운 패키지명으로 사용됩니다. Jakarta EE는 Java EE의 후속으로 이관되었으며, 이에 따라 javax 대신 jakarta 패키지를 사용합니다. 따라서 Jakarta EE 8 이상의 환경에서는 jakarta.persistence.EntityManager를 사용해야 합니다.

두 인터페이스 간의 기능적인 차이는 없으며, Jakarta EE 8 이후 버전에서는 jakarta.persistence.EntityManager를 사용하는 것이 권장됩니다.

jakarta가 더 최신 환경에서 사용하는 패키지인듯? 그리고 내가 현재 jakarta 패키지를 사용하고 있었다.

기능적인 차이는 없어서 단지 패키지만 javax에서 jakarta로 바꿔주면 되는 것 같다.

 

dependencies {
   implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
   implementation 'org.springframework.boot:spring-boot-starter-web'
   implementation 'org.springframework.boot:spring-boot-starter-validation'

   implementation 'com.querydsl:querydsl-core'
   implementation 'com.querydsl:querydsl-jpa'

   annotationProcessor("com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa")

   annotationProcessor("jakarta.persistence:jakarta.persistence-api")
   annotationProcessor("jakarta.annotation:jakarta.annotation-api")

   compileOnly 'org.projectlombok:lombok'
   runtimeOnly 'com.mysql:mysql-connector-j'
   annotationProcessor 'org.projectlombok:lombok'
   testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

내 build.gradle의 dependencies는 다음과 같았다.

 

검색해서 찾아보니

implementation 'com.querydsl:querydsl-jpa' 를 그대로 사용하면 javax.persistence 패키지에 있는 클래스들을

JPA를 구현하는데 사용하게 된다.

 

나는 jakarta 관련 패키지를 사용하고 있기 때문에

jakarta.persistence 패키지의 클래스들을 사용하도록 의존성을 바꿔주면 된다.

 

그래서 다음과 같이 의존성을 수정하였다.

implementation "com.querydsl:querydsl-jpa:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"

가장 뒤에 jakarta를 추가하여 해당 패키지를 사용하게 하였고, 이전과는 다르게 jpa 버전까지 설정해줘야 사용이 가능했다

수동으로 5.0.0 과 같이 구체적인 버전을 지정해줘도 되지만 자동으로 버전을 따라가게 설정해주는 것이 매번 버전을 바꿔줄 필요가 없을 것 같아 저렇게 설정하였다.

 

수정 후 다시 빌드하면 JPAQueryFactory 생성자가 javax.persistence.EntityManager 가 아닌jakarta.persistence.EntityManager 타입의 EntityManager를 인수로 사용하게 되어 에러가 사라진다.

+ Recent posts