묻고 답해요
138만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
상속관계 Joined - 임시 테이블로 생성/삭제로 인한 성능 문제
안녕하세요 영한님.상속관계 Joined 매핑을 사용할 때, 부모테이블에 대하여 업데이트 쿼리 시 임시 테이블 Create Drop 에 대해 질문드리고 싶습니다. 최근에 플젝을 진행하면서 JPA 상속관계 Joined 전략을 활용했는데요, 프로젝트 초기에는 정규화된 테이블 구조로 먼저 진행하고, 추후 성능 이슈가 발생하면 단일 테이블 전략으로 역 정규화를 논의하는 것이 나을 것으로 판단했기 때문입니다.Domain// 부모 엔티티 @Entity @DiscriminatorColumn @Inheritance(strategy = InheritanceType.JOINED) public class Notification { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "notification_id") private Long id; @Enumerated(value = EnumType.STRING) @Column(nullable = false, columnDefinition = "varchar(50)") private NotificationEventType notificationEventType; @Column(nullable = false) private LocalDateTime createdAt; @Column(name = "\"read\"", nullable = false) private Boolean read; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User notifier; }// 자식 엔티티 @Entity public class RecruitmentNotification extends Notification { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "recruitment_id", nullable = false) private Recruitment actor; } @Entity public class StudyNotification extends Notification { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "study_id", nullable = false) private Study actor; } @Entity public class ReviewNotification extends Notification { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "review_id", nullable = false) private Review actor; } Service@Service @RequiredArgsConstructor @Slf4j public class NotificationCommandService { private final NotificationRepositoryImpl notificationRepository; public void updateNotificationsAsRead(final User user, final List<Long> notificationIds) { notificationRepository.updateNotificationsAsRead(user.getId(), notificationIds); } } Repositorypublic interface NotificationJpaRepository extends JpaRepository<Notification, Long> { @Modifying @Query("UPDATE Notification n " + "SET n.read = true " + "WHERE n.notifier.id = :userId AND n.id IN :notificationIds") void updateNotificationsAsRead(final Long userId, final List<Long> notificationIds); } @Repository @RequiredArgsConstructor public class NotificationRepositoryImpl { private final JPAQueryFactory q; private final NotificationJpaRepository notificationJpaRepository; private final EntityManager em; public void updateNotificationsAsRead(final Long userId, final List<Long> notificationIds) { notificationJpaRepository.updateNotificationsAsRead(userId, notificationIds); em.flush(); em.clear(); } } 부모테이블에 대하여 업데이트 쿼리 시, JPA 구현체가 자체적으로 임시 테이블을 Create 및 Drop 하는 로그를 확인했습니다.create temporary table if not exists HT_notification(notification_id bigint not null, primary key (notification_id)) drop temporary table HT_notification 두 가지 문제점이 있다고 생각하는데요.보안 이슈 등을 고려하여, 현재 상용 DB 의 백엔드 사용자 권한에 DDL을 제외하였습니다.이에 따라 임시 테이블을 생성하지 못하고, 500 에러가 발생하는 상황입니다.JPA 상속 관계 매핑 전략만을 위해 DB 사용자 권한을 넓게 가져가는 것이 올바른지 잘 모르겠습니다 🤔 업데이트 API를 호출할 때마다, 임시 테이블을 생성하고 드랍하는 행위가 매우 비효율적이라 생각되는데,이럴 경우 Single 테이블 전략으로 수정하거나, 상속관계 매핑 자체를 안쓰는 방법밖엔 없을까요?상속관계 매핑 전략은 애플리케이션 레벨에서 DB 테이블의 조작을 손쉽게하는 장점이 있긴하지만,결국 상용 서비스 중인 DB를 세팅할 땐 데이터베이스 레벨에서 DDL을 직접 세팅하는게 좋고, 기존의 장점이 상쇄되는 느낌입니다.성능적 손해를 감수하면서도 상속 관계 매핑을 활용하는게 좋은 접근 방법인지 판단이 서지 않아 질문드립니다 🙂
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
상속관계 Joined 매핑 - 임시 테이블 Create Drop에 관하여
안녕하세요 영한님.상속관계 Joined 매핑을 사용할 때, 부모테이블에 대하여 업데이트 쿼리 시 임시 테이블 Create Drop 에 대해 질문드리고 싶습니다. 최근에 플젝을 진행하면서 JPA 상속관계 Joined 전략을 활용했습니다.부모테이블에 대하여 업데이트 쿼리 시, JPA 구현체가 자체적으로 임시 테이블을 Create 및 Drop 하는 로그를 확인했습니다. Domain// 부모 엔티티 @Entity @DiscriminatorColumn @Inheritance(strategy = InheritanceType.JOINED) public class Notification { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "notification_id") private Long id; @Enumerated(value = EnumType.STRING) @Column(nullable = false, columnDefinition = "varchar(50)") private NotificationEventType notificationEventType; @Column(nullable = false) private LocalDateTime createdAt; @Column(name = "\"read\"", nullable = false) private Boolean read; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User notifier; }// 자식 엔티티 @Entity public class RecruitmentNotification extends Notification { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "recruitment_id", nullable = false) private Recruitment actor; } @Entity public class StudyNotification extends Notification { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "study_id", nullable = false) private Study actor; } @Entity public class ReviewNotification extends Notification { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "review_id", nullable = false) private Review actor; } Service@Service @RequiredArgsConstructor @Slf4j public class NotificationCommandService { private final NotificationRepositoryImpl notificationRepository; public void updateNotificationsAsRead(final User user, final List<Long> notificationIds) { notificationRepository.updateNotificationsAsRead(user.getId(), notificationIds); } } Repositorypublic interface NotificationJpaRepository extends JpaRepository<Notification, Long> { @Modifying @Query("UPDATE Notification n " + "SET n.read = true " + "WHERE n.notifier.id = :userId AND n.id IN :notificationIds") void updateNotificationsAsRead(final Long userId, final List<Long> notificationIds); } @Repository @RequiredArgsConstructor public class NotificationRepositoryImpl { private final JPAQueryFactory q; private final NotificationJpaRepository notificationJpaRepository; private final EntityManager em; public void updateNotificationsAsRead(final Long userId, final List<Long> notificationIds) { notificationJpaRepository.updateNotificationsAsRead(userId, notificationIds); em.flush(); em.clear(); } } 업데이트 API를 호출할 때마다, 임시 테이블을 생성하고 드랍하는 행위가 매우 비효율적이라 생각되는데,이럴 경우 Single 테이블 전략으로 수정하거나, 상속관계 매핑 자체를 안쓰는 방법밖엔 없을까요? 상속관계 매핑 전략은 애플리케이션 레벨에서 DB 테이블의 조작을 손쉽게하는 장점이 있긴하지만,결국 상용 서비스 중인 DB를 세팅할 땐 데이터베이스 레벨에서 DDL을 직접 세팅하는게 좋고, 기존의 장점이 상쇄되는 느낌입니다.성능적 손해를 감수하면서도 상속 관계 매핑을 활용하는게 좋은 접근 방법인지 판단이 서지 않아 질문드립니다 🙂
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
Id 대신 name을 사용하는 이유
강의에서 사용자는 Id로 조회하고, 도서는 name으로 조회하는데 별도의 이유가 있을까요?실제 구현한다면 동일한 도서명이 있을 것 같기도 하고, 일관성을 위해 강의를 참고하며개인적으로 두가지 다 Id로 조회하도록 구현하고 있었습니다. Dto나 Repository 등에서 타입과 이름만 잘 변경해주면 문제가 없을꺼라고 생각했는데중간에 제가 잘못 설계한 곳이 있는지 도서 대출시 BookRequestLoan에 값이 계속 안넘어옵니다. 혹시 Id (long 타입)로 조회하면 크게 달라지는 코드가 있거나 주의해야하는 부분이 있는지여쭤보고 싶어서 문의글 남깁니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
여러 서버에서 db 접근 시 동시성문제
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여러 서버에서 db에 접근할 경우 sequence전략의 인덱스 처리가 궁금합니다.allocationsize를 50으로 설정한 경우a 서버에서 1~50까지 확보, 다음 인덱스번호 51번(a서버에서 아직 종료되지 않음)b 서버에서 인덱스번호 요청 51번 반환, 51~100번 인덱스 사용만약 해당 상황의 a서버에서 데이터를 3개 추가한 후 종료된다면 1,2,3번 인덱스만 사용되고 4~50번 인덱스는 앞으로 사용되지 않는건가요??그리고 여러 서버를 작동시키고 이러한 방식으로 사용한다면 중간중간 비어있는 인덱스가 많아질 것인데, 비어있는 인덱스는 재활용이 불가능한지 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
타임리프 템플릿 레이아웃 사용 시 js 안 됨
현재 스프링데이터JPA와 스프링 활용2에서 타임리프를 보며 개인 프로젝트를 진행하던 중 같은 main.html이지만 url이 다르면 js 코드가 적용이 안 되어 도움을 구합니다....user_search.js에서 UserSearchController에 url 매핑을 하여 return으로 그냥 다시 main.html을 호출하는 방식인데 안되네요... 어느 부분이 오류인지 못 찾겠습니다...https://drive.google.com/file/d/19zwAkqf9PijmfLiNzg8amCdJrJtvjsmA/view?usp=sharing
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
JpashopApplication.main()' 에러
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]메인 메서드 실행은 되는데 종료할때 아래와 같은 에러가 납니다. 찾아봐도 해결이 안되네요 도움 부탁드립니다참고용으로 Build.gradle 소스도 함께 올립니다.plugins { id 'java' id 'org.springframework.boot' version '3.3.0' id 'io.spring.dependency-management' version '1.1.5' } group = 'jpabook' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' // Validation (JSR-303 validation with Hibernate validator) 모듈을 꼭! 추가 implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-devtools'// compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //JUnit4 추가 testImplementation("org.junit.vintage:junit-vintage-engine") { exclude group: "org.hamcrest", module: "hamcrest-core" } testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.named('test') { useJUnitPlatform() }
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
window docker rabbitmq 실행시 port access permission 문제로 실패 경우
해당 포트 제한되었는지 확인하여 풀어줘야함 (ex 4369 port)-확인: netsh interface ipv4 show excludedportrange protocol=tcp-해제:net stop winnatnetsh int ipv4 add excludedportrange protocol=tcp startport=4369 numberofports=1net start winnat
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
기본값 타입에 식별자도 포함되는지
JPA에서는 데이터 타입을 톱레벨에서 2가지, 엔티티 타입과 값 타입으로 분류한다고 하는데 식별자도 값 타입 중 기본값 타입으로 분류되는 것이 맞나요? 예를 들어 Member 엔티티에 식별자인 memberId와 필드인 name, age가 있다면memberId, name, age 모두 기본값 타입인 것인지 궁급합니다. 당연한 질문일 수도 있겠지만, 설명하실 때와 강의자료에서 모두 식별자가 기본값 타입이라는 언급을 안하시는 것 같아서 예외적인 부분인가 하여 질문합니다.
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
44강) grep으로 임시 비밀번호가 안뜨는 경우
sudo cat /var/log/mysqld.log | grep "temporary password”이걸로 수정해서 진행해보세요! 출처) https://www.fedoralinux.or.kr/forums/topic/21405
-
미해결Practical Testing: 실용적인 테스트 가이드
테스트 나누는 기준
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 강사님 37분 쯤 test를 주문 생성 시 주문 상태는 INIT이다 라는 test를 하시는데 이를 이전 TotalPrice test하는 testcode와 같이 합쳐서 주문 생성 시 주문 상태는 INIT , TotalPrice를 구할 수 있다 이런식으로 하나로 합치는 건 어떻게 생각하시나요?
-
미해결Practical Testing: 실용적인 테스트 가이드
서비스 레파지토리 의존
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 강사님 강의를 듣던 중 의문점이 생겨 질문을 남깁니다.강의 28분 쯤 OrderService에서 ProductRepository를 의존하게 되는데 보통 A 레파지토리는 A서비스에서만 의존 하고 B레파지토리를 접근하려면 B서비스를 통해 접근한다 라고 들은 기억이 있는데 혹시 강사님만의 기준이 있을까요??감사합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
회원 상속전략
안녕하세요 일정 부분을 공유하는 회원 엔티티를 설계할 때의 상속전략 vs 분리가 궁금합니다.민원인, 직원 이렇게 2종류가 있고 아이디, 비밀번호, 사번 등이 동일하고 직원은 여기서 몇개만 추가된다고 가정한다면엔티티를 따로 분리하는게 아닌 공통속성 엔티티를 상속해서 만들어도 괜찮을까요?몇일을 고민해도 답이 쉽게 나오지 않네요ㅜㅜ
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
mysql 질문이요!
저는 Developer Default가 없는데 그냥 server only로 해도 상관없을까요?
-
미해결Practical Testing: 실용적인 테스트 가이드
RESTFUL API
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. RESTFUL API 방식으로 url 작성 시 강의 13분에 나오는 postmapping에 orders/order이 더 맞지 않나요?? new 보단
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
@PostMapping("/order") 에서 @RequestParam 대신 @ModelAttribute 사용하려면
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.안녕하세요 강의에서 사용하신 코드를 이거에서 @PostMapping("/order") public String createOrder(@RequestParam("itemId") Long itemId, @RequestParam("memberId") Long memberId, @RequestParam("quantity") int quantity) { orderService.order(memberId, itemId, quantity); return "redirect:/"; } 이렇게 ModelAttribute 를 사용해서 변경하고 싶은데 값을 조회해보니까 testForm 값이 안들어가게 되는데 이러한 방식이 왜 불가능한지 알고 싶습니다.@PostMapping("/order") public String createOrder(@ModelAttribute TestForm testForm) { orderService.order(testForm.getMemberId(), testForm.getItemId(), testForm.getQuantity()); return "redirect:/"; }TestForm 의 필드입니다.public class TestForm { private Long memberId; private Long itemId; private int quantity; }감사합니다.
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
GPG 체크 오류
만약 GPG체크오류가 계속 해서 뜬다면 이것을 시도해보세요다운로드한 패키지들을 dnf 명령어를 사용하여 설치합니다. 먼저, 패키지들을 다운로드합니다:wget https://repo.mysql.com/yum/mysql-8.0-community/el/9/x86_64/mysql-community-client-8.0.37-1.el9.x86_64.rpmwget https://repo.mysql.com/yum/mysql-8.0-community/el/9/x86_64/mysql-community-client-plugins-8.0.37-1.el9.x86_64.rpmwget https://repo.mysql.com/yum/mysql-8.0-community/el/9/x86_64/mysql-community-common-8.0.37-1.el9.x86_64.rpmwget https://repo.mysql.com/yum/mysql-8.0-community/el/9/x86_64/mysql-community-icu-data-files-8.0.37-1.el9.x86_64.rpmwget https://repo.mysql.com/yum/mysql-8.0-community/el/9/x86_64/mysql-community-libs-8.0.37-1.el9.x86_64.rpmwget https://repo.mysql.com/yum/mysql-8.0-community/el/9/x86_64/mysql-community-server-8.0.37-1.el9.x86_64.rpm dnf 명령어를 사용하여 GPG 체크 없이 패키지를 설치합니다:sudo dnf install ./mysql-community-client-8.0.37-1.el9.x86_64.rpm --nogpgchecksudo dnf install ./mysql-community-client-plugins-8.0.37-1.el9.x86_64.rpm --nogpgchecksudo dnf install ./mysql-community-common-8.0.37-1.el9.x86_64.rpm --nogpgchecksudo dnf install ./mysql-community-icu-data-files-8.0.37-1.el9.x86_64.rpm --nogpgchecksudo dnf install ./mysql-community-libs-8.0.37-1.el9.x86_64.rpm --nogpgchecksudo dnf install ./mysql-community-server-8.0.37-1.el9.x86_64.rpm --nogpgcheck MySQL 서비스 시작 및 상태 확인sudo systemctl start mysqldsudo systemctl status mysqld이렇게 하면 해결 되는것 같아요 저도 엄청 꼬였는데 이 코드면 해결되네요
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
단일 테이블 전략 조회 성능 임계점
단일 테이블 전략에서 단일 테이블에 모든 것을 저장하기 때문에 테이블이 비대해지고, 이에 따라 조회 성능에 문제가 발생할 수 있다고 하는데임계점을 넘는 경우에만 그렇다 라고 말씀하십니다.일반적으로 임계점은 어느정도인지 궁금합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
실무 백엔드, 프론트엔드 관하여 질문드립니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 아니요2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요?예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]강의의 실습은 Spring + Thymeleaf 를 이용하여 구현하는데, 실제 현업에서는 백엔드와 프론트엔드가 분리되어 각각 개발할 수도 있는데, 타임리프는 JSP와 같이 프론트단에 서버 관련 로직이 연동되어 분리하여 각각 분담하기엔 어려움이나 프론트의 불만이 있지 않을까 생각되는데, 실제 현업에서는 어떻게 진행하는지 궁금합니다. (서버 개발자가 프론트까지 담당하면 어려움이 없겠으나, 분리되어 프로젝트를 진행하는 경우에도 타임리프를 사용하는지 궁금합니다. )(JSP는 공부한적 있지만 실제 현업에서 사용해본적은 없습니다)
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
파일에서 찾기 단축키 알려주실 수 있나요?
혹시 저 파일에서 찾기 단축키가 뭔지 알 수 있을까요???너무 유용해보이는데 여기저기 찾아봐도 잘 못 찾겠어요...
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
컨트롤러에서 어설픈 엔티티를 생성하면 안 되는 이유
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용] 해당 부분에서 컨트롤러에서 어설픈 엔티티를 생성하지 말라고 하셨습니다그 말인 즉슨 컨트롤러에서 준영속 엔티티를 생성해서 운영을 지양하라는 말씀이신데 이유가 궁금합니다준영속 상태의 엔티티는 불안정하니 가급적 자제해야한다는 이유일까요?아니면 단순 서비스 계층에 수정할 파라메터만 "명확"하게 던지는 게 좋은 설계이므로 그렇게 말씀하신 건가요?