묻고 답해요
163만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! 스프링 데이터 JPA
isNew() 메서드의 구현체 문의
안녕하세요! isNew() 메서드의 구현체가 정확히 무엇인지 확인하고 싶어 질문드립니다!SimpleJpaRepository의 save() 메서드 내부에서 isNew() 메서드가 호출될 때,if (entityInformation.isNew(entity)) {처럼 호출되는데요, 이 때 isNew 가 org.springframework.data.repository.core.EntityInformation 인터페이스의 추상 메서드인 것을 확인했습니다.그런데 이 isNew 의 구현체가 여러개라서 하나씩 확인해보니 강의에서 설명해주신 내용이 추상 클래스 org.springframework.data.repository.core.support.AbstractEntityInformation 에 구현된 내용과 같더라고요.// AbstractEntityInformation.isNew() public boolean isNew(T entity) { ID id = getId(entity); Class<ID> idType = getIdType(); if (!idType.isPrimitive()) { return id == null; } if (id instanceof Number) { return ((Number) id).longValue() == 0L; } throw new IllegalArgumentException(String.format("Unsupported primitive id type %s", idType)); }그런데 AbstractEntityInformation 역시 추상 클래스이다 보니 정확한 구현체를 찾기가 힘든 상태입니다. 질문) SimpleJpaRepository의 save() 내부에서 사용되는 isNew() 의 구현체는 정확히 어떤 클래스인가요? 또, 이러한 구현체가 정확히 무엇인지 알 수 있는 방법이 있을까요?확인해주셔서 감사합니다. :D
-
미해결
스프링 인터셉터가 동작하지 않아 질문드립니다.
안녕하세요, 스프링 MVC 강의를 완강이후 프로젝트를 수행중인 학부생입니다.로그인 기능 구현과 관련하여 강의 예제 코드를 참고하며 구현하던 중이해할 수 없는 현상이 발생하여 질문 드립니다. 코드LoginInterceptor.javapackage Alchole_free.Cockpybara.interceptor; import Alchole_free.Cockpybara.constant.SessionLoginConst; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @Slf4j //@Component public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); log.info("session = {}", session); if(session==null || session.getAttribute(SessionLoginConst.LOGIN_MEMBER)==null){ log.info("로그인되지 않은 사용자"); response.sendRedirect("/login"); return false; } log.info("정상 요청"); return true; } } WebConfig.javapackage Alchole_free.Cockpybara.config; import Alchole_free.Cockpybara.interceptor.LoginInterceptor; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; //@Slf4j @Configuration //@RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { // private final LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .order(1) .addPathPatterns("/**") .excludePathPatterns("/", "/join", "/login", "/css/**", "/*.ico", "/error"); } } 문제위와 같이 코드를 구성하고 애플리케이션을 동작시켰는데, 인터셉터가 아예 로그에 남지않는(생성되지 않는 것으로 보이는) 현상이 발생하였습니다. 관련하여 구글링을 하다보니인터셉터 클래스를 빈으로 등록해주는 형태가 아니면 동작하지 않을 수 있다고 하여,빈으로 등록하고 WebConfig 클래스에서 생성자를 통해 주입받는 형태로 구현도 해보았는데여전히 같은 문제가 발생하더군요. 도대체 어느 부분에서 문제가 발생하는 것인지파악하기가 힘들어 고민끝에 질문드립니다. 혹시 몰라 아래 빌드, 설정 파일도 첨부합니다. 문제 실행 화면/hello 로 Controller @GetMapping 메서드를 구현해놓고 요청을 보냈으나 인터셉터 관련 로그가기록되지 않는 모습입니다.build.gradleplugins { id 'java' id 'org.springframework.boot' version '2.7.13' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'Alchole_free' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '11' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } 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' compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //swagger 설정 implementation group:'io.springfox', name:'springfox-swagger2', version:'2.8.0' implementation group:'io.springfox', name:'springfox-swagger-ui', version:'2.8.0' } tasks.named('test') { useJUnitPlatform() } application.properties# ?????? ?? ?? spring.datasource.url=jdbc:mariadb://localhost:3306/cockpybara spring.datasource.username=root spring.datasource.password=cockpybara spring.datasource.driver-class-name=org.mariadb.jdbc.Driver # JPA ?? spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create spring.jpa.properties.hibernate.format_sql=true //JPA ???? Hibernate? ????? ???? SQL? formating?? ?? spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect #show parameter binding logging.level.org.hibernate.type.descriptor.sql=DEBUG logging.level.org.hibernate.SQL=DEBUG
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
jpa 테이블 생성 시 질문
로컬서버에서 appication.yml 에jpa:hibernate:ddl-auto: create이렇게 설정하면 테이블이 전체 지워지고 다시 생성되는 것까지 이했습니다. 그런데 만들어놓은 테이블은 그대로 두고 새로운 컬럼이나 테이블을 추가한거만 업데이트를 하면 좋을 거같은데 구글링 해봐도 잘모르겠네요 ㅜ 자꾸 테이블을 지우고 다시 생성하니까 테스트하기가 좀 힘든거같아요. 혹시 방법이 있을까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
컬렉션의 필요성에 대해 질문 좀 드리겠습니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예[질문 내용]먼저 다 대 다 관계라고 하겠습니다.A라는 엔티티와 B라는 엔티티가 다대다로 묶여져 있고 그 중간테이블을 C라고 하겠습니다.이럴 경우에 걍 컬렉션 배치size으로 하는게 아니라 중간 테이블 B로 하면 안되나요?요약하면 강의에서는 페이징이 필요하지 않으면 join fetch로 페이징이 필요하다면 batch size를 활용하라 라고 되어있는데 역으로 @ManyToOne이 있는 다대 일의 다 쪽에서 jon fetch로 모든 것을 해결하면 안되는 건가요?? 아 그리고 질문이 또 있는데 위에서 B에서 A와 C를 fetch join으로 모두 가져오게 설계해도 괜찮죠??
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
OrderServiceTest 시 OrderItem 을리스트로 넘길때
안녕하세요. 강의 기준으로 응용하고 싶어서 orderitem을 한개가 아닌 여러개생성하고 주문하려고 하고 있는데 테스트java @Test @Rollback(value = false) public void 상품주문() throws Exception{ Member member = new Member(); member.setName("회원1"); member.setLoginId("admin"); member.setPassword("admin"); member.setEmail("admin"); em.persist(member); Item item = new Item(); item.setItemName("티셔츠1"); item.setPrice(100000); em.persist(item); OrderItem order1 = OrderItem.createOrderItem(item, item.getPrice(), 2,"blue","L"); OrderItem order2 = OrderItem.createOrderItem(item, item.getPrice(), 4,"blue","L"); List<OrderItem> orders = new ArrayList<>(); orders.add(order1); orders.add(order2); Long orderId = orderService.order(member.getId(), item.getId(), orders); Order findOrder = orderRepository.findOne(orderId); Assert.assertEquals("상품 주문시 상태는 : ", OrderStatus.ORDER,findOrder.getOrderStatus()); }OrderService.java @Transactional public Long order(Long memberId, Long itemId, OrderItem... orderItems) { //엔티티 조회 Member member = memberRepository.findOne(memberId); Item item = itemRepository.findOne(itemId); List<OrderItem> orders = new ArrayList<>(); //주문상품 생성 for(OrderItem order : orderItems){ OrderItem orderItem = OrderItem.createOrderItem(item,item.getPrice(),order.getQuantity(),order.getColor(),order.getSize()); orders.add(orderItem); } // 주문 생성 Order order = Order.createOrder(member, (OrderItem) orders); //주문 저장 orderRepository.save(order); return order.getId(); }OrderItem... orderItems 파라미터가 list를 받지 못하는거같은데 혹시 어떻게 해야할까요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
Member 에 orders 를 넣는 구조
Member 객체에서 orders 를 넣는 구조는 좋지 않은 설계라고 하셨는데 여기에 궁금한 점이 있어서 질문합니다! (10분쯤) 이커머스 사이트를 볼때, 로그인을 하게 되면 마이페이지가 있고 마이페이지에는 그 회원의 주문내역이나 그동안 주문했던 것들을 볼 수 있는게 꼭 있는거 같습니다. 이럴때 Member 에 orders 라는 필드가 있어야 좀 더 효과적으로 가지고 올 수 있다고 생각하는데 영한님께서는 좋지 않은 설계라고 하셔서 제 생각이 틀린건지 궁금합니다!
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
블로그 포스팅 관련 문의
안녕하세요 강사님먼저 좋은 강의 만들어주셔서 감사드립니다. 다름이 아니라 혹시 강의 내용과 pdf 강의 자료를 개인 블로그에 정리해서올려도 되는지 여쭙고자 글 남겨드렸습니다.다른 분들과 공유보다는 스스로 복습하는 용도로 글을 작성하는 목적이 크지만 인터넷에 올라오는 내용인 만큼 먼저 허락을 구하고자 합니다.최대한 지양하겠지만 가끔씩 강의 혹은 pdf 파일 속 그림이나 사진을 올리는 경우가 있을 수도 있을 것 같습니다만 이 때는 당연히 출처를 남기겠습니다.만약 불가하시다면 비공개 처리하여 공유 및 열람이 안 되도록 조치해놓겠습니다.감사합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
EntityManager를 사용하는 방법
https://www.inflearn.com/questions/152202/%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98-%EA%B4%80%EB%A0%A8-%EC%A7%88%EB%AC%B8%EB%93%9C%EB%A6%BD%EB%8B%88%EB%8B%A4위에 답변을 보면@Autowired가 스프링 빈을 주입한다면, @PersistenceContext는 JPA 스펙에서 제공하는 기능인데, 영속성 컨텍스트를 주입하는 표준 애노테이션입니다. 라고 적혀있습니다.(1) 그럼 @Autowired로 EntityManager 를 사용시 영속성 컨텍스트를 만들지 못하는 건가요??근데 @Autowired로 받아도 em.persist(member); 가되는 거보면 아닌것 같다고 생각이 드는데...답변의 의미를 잘 모르겠습니다. (2) 구글링한 결과로는 둘의 차이는 쓰레드 간에 동시성문제를 해결하여 EntityManager를 공유하지 않는다로 보이는데 이것을 말씀하신 걸까요??
-
미해결Practical Testing: 실용적인 테스트 가이드
테스트 동시성 관련 질문드립니다
안녕하세요 강의 다 듣고 기능 추가해 가며 공부를 하고 있습니다. 그러다 막히는 부분이 있어 질문드리는데 강의 내용을 조금 벗어 나는거 같아 질문을 드려도 될지 모르겠는데 괜찮으시다면 답변 주시면 감사하겠습니다. @Transactional public OrderResponse createOrder(OrderCreateServiceRequest request, LocalDateTime registeredDateTime) { List<String> productCodes = request.getProductCodes(); List<Product> products = findProductsBy(productCodes); Member member = memberRepository.findByPhoneNumber(request.getPhoneNumber()).get(); deductStockQuantities(products); Order order = Order.create(products, member, registeredDateTime); return OrderResponse.of(orderRepository.save(order)); }order를 생성하는 부분에서 재고 감소 되는 부분을 동시성 처리를 해보려 하는데 테스트 코드에선 deductStockQuantities로 넘어가서 findAllByProductCodeIn 만 한번 돌고 롤백이 되더라구요. @Test public void create_order_with_concurrent_5_request() throws InterruptedException { //given createProducts(); OrderCreateServiceRequest request1 = OrderCreateServiceRequest.builder() .productCodes(List.of("A002","A003")) .phoneNumber("010-1111-2222") .build(); OrderCreateServiceRequest request2 = OrderCreateServiceRequest.builder() .productCodes(List.of("A002","A003")) .phoneNumber("010-1111-2222") .build(); OrderCreateServiceRequest request3 = OrderCreateServiceRequest.builder() .productCodes(List.of("A002","A003")) .phoneNumber("010-1111-2222") .build(); int numberOfThreads = 3; ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads); CountDownLatch latch = new CountDownLatch(numberOfThreads); //when executorService.submit(() -> { try { orderService.createOrder(request1, LocalDateTime.now()); }finally { latch.countDown(); } }); executorService.submit(() -> { try { orderService.createOrder(request2, LocalDateTime.now()); }finally { latch.countDown(); } }); executorService.submit(() -> { try { orderService.createOrder(request3, LocalDateTime.now()); }finally { latch.countDown(); } }); latch.await(); //then List<Stock> stocks = stockRepository.findAllByProductCodeIn(List.of("A002","A003")); assertThat(stocks).hasSize(2) .extracting("productCode", "quantity") .containsExactlyInAnyOrder( tuple("A002", 7), tuple("A003", 7) ); } @Lock(LockModeType.PESSIMISTIC_WRITE) List<Stock> findAllByProductCodeIn(List<String> productCodes);테스트 코드는 구글링해서 넣어보았는데 이런 부분 관련해서 따로 배운게 없어 잘 안되더라구요. 락도 걸어보고 했는데 어디서 안되는지 잘 모르겠어서 질문드립니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
default_batch_fetch_size 크기 질문
강의에서default_batch_fetch_size가 100이고,OrderItem의 크기는 2개,Item의 크기는 4개 입니다default_batch_fetch_size를 정할때 OrderItem의 크기와 Item의 크기를 더한 값인가요? 아니면 OrderItem의 크기만 인건가요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
메인 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.실행시키면 실행이 되다가 갑자기 이런 오류가 뜹니다... 설정이나 설치 등은 그대로 따라했습니다.
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
질문있습니다
강사님이 올려주신 파일이 아니라 Spring Initializr여기서 직접 생성한 다음에 프로젝트를 진행하려고 하는데 이노테이션 ?에노테이션이 안먹습니다.. 아마 그래들 파일 문제인것 같은데 강사님 올려주신 동영상에는 그래들파일 수정하라는 말은 없었거든요 ;; 빠른답변 부탁드립니다 그리고 MYSQL 설치할떄도 디폴트디벨로퍼 항목이 없습니다;; 강좌 왜이런지 ;;
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
상속관계와 식별관계
ERD에서 1대 1 식별 관계로 설계된 경우엔티티 설계는 상속관계로 매핑해야하나요? 식별관계로 매핑해야하나요?이 둘의 차이가 뭔지 궁금합니다!
-
미해결생산성을 향상시키는 스프링부트 기반의 API 템플릿 프로젝트 구현
안녕하세요 강사님 active profiles 관련해서 궁금한게 있습니다
보통 아래와같이yml 파일에 이 yml의 profiles가 dev야 라고 명시 해주고 spring: profiles: dev인텔리제이 active profiles에서 dev를 넣어주면매칭이 되는걸로 알고있는데,별도로 안적어주면application-과 .yml 사이에 있는 파일명을 profiles로 인식을 하는건가요?yml 설정 (3) 강의 보고 질문드립니다!
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
JPA 실무에서 복합키를 사용하는지 궁금합니다!
안녕하세요 현재 JPA 강의를 모두 듣고 프로젝트를 진행하려고 하는 한 학생입니다. 컨설턴트님이 말하시길, RDB에서는 Index를 통한 조회가 생명이다. 또한 매핑되는 테이블의 경우는 데이터가 계속해서 많이 쌓이기 때문에 auto_increment를 통한 Id 설정보다는 복합키를 설정해서 테이블을 생성하는게 조회 성능에서는 월등히 빠르다. 현재 프로젝트의 볼륨의 경우에는 둘 중 무엇을 선택할지는 자유라고 본다. 그러나 개발자로써 의미있는 테이블 설계를 하고싶다면 조금은 번거롭더라도 복합키로 설정하는 것이 좋다고 보는 견해다.라고 말씀을 하셨는데 JPA 에서도 @Embedded나 @IdClass를 사용한 복합키 사용이 효율적일까요? 또한 복합키를 사용하면 QueryDsl을 사용 할 수있는지 궁금합니다!!
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
mysql 설치 중 질문
mysql 설치 중 developer default라는게 안떠서 custom을 눌러서 connector들을 직접 추가해주려고 하는데 현재 8.0.34 버전은 안뜨네요 혹시 connector는 다른 버전을 설치해도 될까요? 그리고 만약 설치한다면 x86으로 돼있던데 제 컴퓨터는 64비트인데 설치해도 되는건가요??아 그리고 제가 예전에 mysql을 설치했었다가 오류가 떠서 완전히 지우고 이번에 다시 설치하는겁니다.
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
H2에 member테이블이 생성안됨
섹션1의 h2데이터베이스 설치에서 설명한대로 하고 있는데접속은 되는데 계속 member 테이블 생성이 안되네요ㅠㅠ.yml 파일도 바꿔보고 dependencies도 비슷한 질문들 찾아가면서 다 바꿨는데 왜 이러는건지 모르겠네요jpahsop.mv.db도 제대로 생성된 상황입니다. 이게 제 yml파일이고spring: config: import: device.yml datasource: url: jdbc:h2:tcp://localhost/~/jpashop username: sa password: driver-class-name: org.h2.Driver jpa: hibernate: # 알아서 table을 생성해줌 ddl-auto: create properties: hibernate: format_sql: true logging.level: org.hibernate.SQL: debug org.hibernate.type: trace 이건 gradle.build의 dependencies입니다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' implementation 'org.springframework.boot:spring-boot-starter-jdbc' testImplementation 'junit:junit:4.13.1' testImplementation 'junit:junit:4.13.1' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' }강사님께서는 run하면 console창에 create Member가 뜨는데 저는 안뜨는게 주원인인거 같습니다...어딜 손봐야하는 걸까요??
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
Filter우선순위 질문
안녕하세요! MSA강의 섹션2 Logging Filter관련 부분 듣다가 필터 우선순위와 관련된 궁금증이 생겨서 질문 남깁니다! GatewayFilter filter = new OrderedGatewayFilter((exchange, chain) -> { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); log.info("Logging Filter base message: {}",config.getBaseMessage()); if(config.isPreLogger()){ log.info("Logging Filter Start: request uri -> {}",request.getURI()); } //Custom Post Filter return chain.filter(exchange).then(Mono.fromRunnable(()->{ if(config.isPostLogger()){ log.info("Logging Filter End: response Code -> {}",response.getStatusCode()); } })); }, Ordered.HIGHEST_PRECEDENCE); return filter;위와 같은 방식으로 OrderedGatewayFilter를 사용해 filter를 생성했는데 이때 두번째 인자로 Ordered.HIGHEST_PRECEDENCE를 사용할 때와 Ordered.LOWEST_PRECEDENCE를 사용할 때 등장하는 filter 우선순위와 관련된 궁금증이 생겼습니다.HIGHEST를 사용할때는 우선순위가 높은 필터가 먼저 나와서 강의에서도 그렇고 코드 실행결과LoggingFIlter -> GlobalFilter -> CustomFilter의 순서로 Filter 가 등장했는데 그렇다면, 반대로 우선순위가 낮은 경우인 LOWEST를 사용할 때는 CustomFilter -> GlobalFilter -> LoggingFIlter의 순서로 filter가 등장해야한다고 생각하는데 결과가 그렇지 않아서 우선순위에 어떠한 개념이 있는지, 제가 어떤 개념을 놓치고 있는지 의문이 들어 질문글 남깁니다!
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
h2 데이터베이스 연결시 포트번호 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]현재 8082번은 다른 프로젝트 때문에 application.properties에서server.port=8083 로8083번으로 바꿔놨습니다. 여기서 h2.bat 파일을 실행했을 때이렇게 이미 포트 번호가 사용 중이라는 오류가 뜹니다. 그래서 cmd에서netstat -ano | findstr :8083로태스크의 pid를 찾아 해당 태스크를 죽이고,H2 콘솔을 실행시키면당연히 스프링부트에서 이미 포트 번호가 사용 중이라는 오류가 뜹니다. 부트에서 포트 번호를 사용하면 H2에서 안되고H2에서 포트 번호를 사용하면 부트에서 안됩니다. 서버를 통해서 DB에 접속하려는 건데 왜 이런 오류가 뜰까요..서버에서 정상적으로 h2를 연결하고 싶습니다. 혹시 application.properties에서 server.port= 명령어로 임의로 포트를 바꿨기 때문인가요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
JPA> DDD 서로 다른 애그리거트 사이의 간접참조
안녕하세요 영한님! 프로젝트에 JPA 및 DDD를 적용하며 의문점이 생기는 부분이 있는데 물어볼 곳이 마땅치 않아서, 이렇게 질문글 올립니다. 구조(요약) - 모노리틱저희 프로젝트에서 다음과 같이 서로 다른 애그리거트 사이에는 간접참조를 통해 느슨하게 결합하여 사용하고 있습니다. 질문다음과 같이 설정하고 나니 몇 가지 의문점이 있습니다. 간접 참조를 통해 느슨한 결합을 하고 있는데, DB 에 따로 외래키 제약 조건을 걸어주어야하는가? 이 부분에 있어서 팀원과 의견이 달라서요. 저는 애그리거트를 나눈 목적이 결국 복잡도를 줄이기 위해서이고, 각각의 애그리거트 안에서 트랜잭션으로 관리가 되어야한다고 생각을 하는데.. 외래키를 설정하면 결국은 User 를 관리할 때 참조 무결성을 신경쓰면서 Trip 까지 고려를 해야돼서 좋지 않다고 생각합니다. 굳이 DB에서 외래키 제약을 걸지 않아도 이벤트를 통해 관리할 수 있다고 생각을 하기도 하구요. 팀원분은 어플리케이션보다는 변경점이 낮은 DB를 우선으로 하며 개발을 해야하고, 그렇기 때문에 반드시 외래키를 걸어주어야한다고 말씀하시는데, 무엇이 더 맞는 말인지 잘 모르겠습니다. 회원 탈퇴(User 삭제)가 이루어질 때 회원과 관련된 모든 Trip 삭제(벌크성 삭제 쿼리)가 이루어지도록 하기 위해서 이벤트를 활용하고 있는데, 이를 비동기적으로 처리해도 문제가 되지 않는가?@Async, @TransactionalEventListener 를 활용해서 회원탈퇴 요청시 회원 삭제가 커밋이 완료 되면 회원이 작성한 여행 정보를 지우는 비동기 이벤트를 발행하도록 하고 있습니다. 회원 탈퇴시 중요한건 회원 정보를 삭제하는 것이라고 생각해서 이를 비동기적으로 처리하는게 옳다고 생각해서 이렇게 구현했는데, 이 방식이 옳은 방식인지 확신이 서질 않습니다. 현업에서는 어떻게 이런 문제를 해결하고 있는지 궁금합니다! 읽어주셔서 감사합니다!