11강 [실습] Docker로 MySQL1 분만에 실행하기
docker실행하여 mySql 컨테이너 생성까지 성공했습니다.
하지만 마지막 부분의 어플리케이션 실행 부분에서 에러가 나오고 있습니다.
org.hibernate.exception.AuthException: Unable to obtain isolated JDBC connection [Access denied for user 'coupon'@'localhost' (using password: YES)] [n/a]
Caused by: java.sql.SQLException: Access denied for user 'coupon'@'localhost' (using password: YES)
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/hibernate/autoconfigure/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
Caused by: org.hibernate.HibernateException: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
어떻게 대응해야 할까요?
Câu trả lời 2
1
안녕하세요, Jang Jaehoon 님
위 쪽의 Access denied 문제만 해결하면 될 것 같은데요.
원인을 짐작할 수 있는 단서는 에러 메시지의 'coupon'@'localhost' 부분입니다. 강의에서 사용하는 mysql:8.4 이미지는 PC에서 Docker 컨테이너의 MySQL로 접속하면 접속자가 'coupon'@'172.x.x.x'처럼 IP 주소로 기록됩니다.
그런데 질문 주신 에러에는 localhost로 찍혀 있으니, 애플리케이션이 Docker 컨테이너가 아니라 PC에 직접 설치된 다른 MySQL에 접속했을 가능성이 높습니다. 로컬에 설치된 MySQL이 이미 3306 포트를 쓰고 있으면 컨테이너는 정상적으로 떠 있어도 localhost:3306으로 들어온 요청을 로컬 MySQL이 받아 가게 되고, 그 MySQL에는 coupon 계정이 없으니 Access denied가 나는 것입니다.
1 실행중인 컨테이너 MySQL 계정 확인)
먼저 컨테이너 쪽 계정이 정상인지 확인해 보시면 좋겠습니다. docker-compose.yml이 있는 디렉터리에서 아래 명령을 실행했을 때 1이 출력된다면 컨테이너에 자체는 문제가 없음을 확인할 수 있습니다.
docker compose exec mysql mysql -ucoupon -pcoupon coupon -e "select 1"
만약 위의 확인 명령에서부터 Access denied가 난다면, 볼륨에 예전 데이터가 남아 있는 경우일 수 있습니다. MySQL 이미지는 데이터 디렉터리가 비어 있을 때 딱 한 번만 MYSQL_USER, MYSQL_PASSWORD로 계정을 만들기 때문에, 이전에 다른 설정으로 컨테이너를 띄운 적이 있다면 compose 파일을 고쳐도 반영되지 않습니다. 이때는 docker compose down -v로 볼륨까지 지운 뒤 docker compose up -d mysql로 다시 띄워 주세요. 볼륨을 지우면 DB 데이터가 모두 삭제된다는 점은 참고해 주세요.
또 IntelliJ Run Configuration에 SPRING_DATASOURCE_PASSWORD 같은 환경 변수를 넣어 두셨다면 그 값이 application.yaml 기본값보다 우선하니 함께 확인해 보시면 좋겠습니다.
2 다른 MySQL 프로세스가 있는지 확인)
다음으로 3306 포트를 어떤 프로세스가 쓰고 있는지 확인해 주세요.
macOS에서는 lsof -nP -iTCP:3306 -sTCP:LISTEN,
Windows에서는 netstat -ano | findstr :3306으로 확인할 수 있습니다.
결과에 mysqld가 보이면(Windows는 출력된 PID를 작업 관리자에서 찾아보시면 됩니다) PC에 설치된 MySQL이 포트를 차지하고 있는 것입니다.
이 경우 해결 방법은 두 가지입니다.
하나는 로컬 MySQL을 중지하는 방법으로,
Homebrew로 설치하셨다면 brew services stop mysql,
Windows라면 services.msc에서 MySQL80 서비스를 중지하신 뒤 docker compose up -d mysql로 컨테이너를 다시 띄우고 애플리케이션을 실행하시면 됩니다.
다른 하나는 로컬 MySQL은 그대로 두고 컨테이너 포트를 바꾸는 방법입니다. docker-compose.yml의 포트를 "3307:3306"으로 바꾸고, application.yaml의 url 기본값도 jdbc:mysql://localhost:3307/coupon으로 맞춰 주시면 됩니다.
그래도 해결되지 않으면 위 두 확인 명령의 출력 결과를 댓글로 남겨 주세요. 같이 확인해보겠습니다.
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다. Jang Jaehoon님.
Access denied for user 'coupon'@'localhost' 오류는 애플리케이션이 MySQL에 접속할 때 사용한 coupon 계정의 비밀번호가 다르거나, 해당 계정이 올바르게 생성되지 않았을 때 주로 발생합니다. 먼저 Docker MySQL 컨테이너의 환경 변수와 Spring Boot의 datasource 설정을 비교해 주세요.
- MySQL 컨테이너의
MYSQL_USER,MYSQL_PASSWORD,MYSQL_DATABASE
- Spring Boot의
spring.datasource.username,spring.datasource.password,spring.datasource.url
특히 MySQL Docker 컨테이너를 생성한 뒤 환경 변수를 변경했다면, 기존 데이터 볼륨에 설정이 남아 변경 사항이 반영되지 않을 수 있습니다. 이 경우 컨테이너와 볼륨을 정리한 후 올바른 계정 정보로 다시 생성해야 할 수 있습니다.
Unable to determine Dialect without JDBC metadata는 Hibernate가 데이터베이스에 연결하지 못해 DB 종류를 확인하지 못하면서 연쇄적으로 발생한 오류일 가능성이 높습니다. 따라서 우선 Hibernate Dialect를 설정하기보다는 MySQL 접속 정보와 계정 권한을 먼저 확인하는 것이 좋습니다.
유사한 오류와 Docker MySQL 접속 정보 확인 방법은 아래 질문을 참고해 주세요.
해당 답변처럼 docker ps로 MySQL 컨테이너가 실행 중인지 확인하고, 컨테이너 실행 시 지정한 계정 정보가 애플리케이션 설정과 일치하는지 확인해 보세요. 또한 JDBC URL의 호스트도 실행 환경에 맞아야 합니다. 애플리케이션을 로컬에서 실행한다면 일반적으로 localhost:호스트에 매핑한 포트를 사용하고, 애플리케이션도 Docker 컨테이너에서 실행한다면 localhost 대신 MySQL 컨테이너 이름을 사용해야 합니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
Tasklet 배치 관련 내용
0
9
1
verify.sh 4단계 실패 — Jenkins 컨테이너에서 127.0.0.1:6443 connection refused
0
13
1
조회 메서드 네이밍 질문
0
20
0
소스파일
0
27
1
강의 판서 자료
0
24
2
모의고사 파일오류
0
54
3
Properties 설정이 추가되었는데
0
26
1
아무 수정도 안하고 주어진 소스로 그대로 했는데 패스워드 에러가 남
1
44
1
[환불 승인 요청] 강의 오결제 및 재구매 관련 문의드립니다.
0
32
1
처음 실행 시 계속 패스워드가 틀리다고 나옴. 수정하고 해도 마찬가지임
1
51
2
모의고사 다운
0
40
1
강의 DB데이터 질문
0
38
1
22강 [토큰 저장] 질문
0
41
1
업캐스팅 원칙
0
55
2
섹션 2 - 9강. API 관련 질문
0
54
2
11강 [실습] Docker로 MySQL1 분만에 실행하기
0
51
2
@Modifying에 관하여
1
55
1
Issuance 테이블에 status, couponId 인덱스가 꼭 필요할까요?
2
68
1
부하 테스트 시 설정 관련 질문드립니다
1
97
2
kafka 이벤트 발행 실패 시 at-least-once를 보장하는 방법이 궁금합니다.
2
116
1
domain에 @Entity 와 Repository를 함께 둔 이유가 궁금합니다
1
98
1
Jib 이미지 빌드에서 docker credential 관련으로 이슈가 있다면
1
127
1
스크립트에 대해 질문 있습니다.
1
97
1
같은 사용자가 연속된 중복 호출할 경우 어떻게 되는지 궁금합니다!
2
116
1

