묻고 답해요
131만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 핵심 원리 - 기본편
타입 조회 관련 질문 드립니다
스프링 빈 - 동일한 타입이 둘 이상에서 타입으로 조회시 같은 타입이 둘 이상 있으면 중복 오류가 발생한다고 말씀을 하셨는데 이번 강의(스프링 빈 - 상속관계)를 들으니 이전 케이스가 같은 타입으로 조회를 했기에 생겼던 문제인지가 궁금해 졌습니다 예를 들어 코드가 아래와 같은 경우 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SameBeanConfig.class); @Test@DisplayName("타입으로 조회시 같은 타입이 둘 이상 있으면, 중복 오류가 발생한다.")void findByBeanTypeDuplicate(){ assertThrows(NoUniqueBeanDefinitionException.class,()->ac.getBean(MemberRepository.class));} @Configurationstatic class SameBeanConfig{ @Bean public MemberRepository memberRepository1(){ return new MemoryMemberRepository(); } @Bean public MemberRepository memberRepository2(){ return new MemoryMemberRepository(); }} 위의 코드는 타입으로 빈을 조회할 때 MemberRepository를 줍니다. 이걸 주면 오늘 배운 상속 내용처럼 이걸 구현한 MemoryMemberRepository를 가지고 오게 되는데이 자식이 2개가 존재하므로 이번 강의 설명처럼 부모 타입으로 조회하였는데 자식 타입이 2개가 나왔으므로 에러가 생긴 케이스 같습니다.(만약 해당 문제가 싱글톤 컨테이너와 관련이 되어 있는 문제라면 제가 생각한 아래의 구상이 맞는건지 궁금합니다)
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
기능테스트시, setName() 등 메서드 오류
기능테스트시 아래에 빨강 음영부분에 의해 진행이 되질 않습니다. 해당 문제는 상속문제라 생각하여, 해당 코드를 아래에 올렸습니다. 왜 Item. Book class의 변수에 관한 메서드가 문제가 되는지 조언 부탁드립니다. package jpabook.jpashop.service;import jpabook.jpashop.domain.Address;import jpabook.jpashop.domain.Member;import jpabook.jpashop.domain.Order;import jpabook.jpashop.domain.OrderStatus;import jpabook.jpashop.domain.item.Item;import jpabook.jpashop.exception.NotEnoughStockException;import jpabook.jpashop.repository.OrderRepository;import org.junit.Assert;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.context.annotation.EnableMBeanExport;import org.springframework.test.context.junit4.SpringRunner;import org.springframework.transaction.annotation.Transactional;import javax.persistence.EntityManager;import java.awt.print.Book;import static org.junit.Assert.*;@RunWith(SpringRunner.class)@SpringBootTest@Transactionalpublic class OrderServiceTest { @Autowired EntityManager em; @Autowired OrderService orderService; @Autowired OrderRepository orderRepository; /** * 상품 주문 */ @Test public void order() { // given Member member = createMember(); Book book = createBook("시골 JPA", 10000, 10); int orderCount = 2; // when Long orderId = orderService.order(member.getId(), book.getId(), orderCount); // then Order getOrder = orderRepository.findOne(orderId); assertEquals("상품 주문시 상태는 ORDER", OrderStatus.ORDER, getOrder.getStatus()); assertEquals("주문한 상품 종류 수가 정확해야 한다.", 1, getOrder.getOrderItems().size()); assertEquals("주문 가격은 가격 * 수량이다.", 1000 * orderCount, getOrder.getTotalPrice()); assertEquals("주문 수량만큼 재고가 줄어야 한다.", 8, book.getStockQuantity()); } /** * 주문취소 */ @Test public void cancelOrder() { Member member = createMember(); Book item = createBook("시골 JPA", 10000, 10); int orderCount = 2; Long orderId = orderService.order(member.getId(), item.getId(), orderCount); orderService.cancelOrder(orderId); Order getOrder = orderRepository.findOne(orderId); assertEquals("주문 취소시 상태는 CANCEL 이다.", OrderStatus.CANCEL, getOrder.getStatus()); assertEquals("주문이 취소된 상품은 그만큼 재고가 증가해야한다.", 10, item.getStockQuantity()); } /** * 재고수량 초과 */ @Test(expected = NotEnoughStockException.class) public void 상품주문_재고수량초과() throws Exception{ // given Member member = createMember(); Item item = createBook("시골 JPA", 10000, 10); int orderCount = 11; // when orderService.order(member.getId(), item.getId(), orderCount); // then fail("재고 수량 부족 예외가 발생해야 한다."); } private Book createBook(String name, int price, int stockQuantity) { Book book = new Book(); book.setName(name); book.setPrice(price); book.setStockQuantity(stockQuantity); em.persist(book); return book; } private Member createMember() { Member member = new Member(); member.setName("회원1"); member.setAddress(new Address("서울", "강가", "123-123")); em.persist(member); return member; } package jpabook.jpashop.domain.item;import jpabook.jpashop.domain.Category;import jpabook.jpashop.exception.NotEnoughStockException;import lombok.Getter;import lombok.Setter;import javax.persistence.*;import java.util.ArrayList;import java.util.List;@Entity@Inheritance(strategy = InheritanceType.SINGLE_TABLE)@DiscriminatorColumn(name = "dtype")@Getter @Setterpublic abstract class Item { @Id @GeneratedValue @Column(name = "item_id") private Long id; private String name; private int price; private int stockQuantity; @ManyToMany(mappedBy = "items") private List<Category> categories = new ArrayList<>(); // == 비즈니스 로직 == // // stockQuantity의 경우, Item 엔티티 내에만 있으므로 해당 클래스에서 비즈니스 로직을 설정(엔티티 주도 설계) /** * 재고 수량 증가* * */ public void addStock(int quantity){ this.stockQuantity += quantity; } /** * 재고 수량 감소* * */ public void removeStock(int quantity){ int restStock = this.stockQuantity - quantity; if(restStock<0){ throw new NotEnoughStockException("need more stock"); } this.stockQuantity = restStock; }} package jpabook.jpashop.domain.item;import lombok.Getter;import lombok.Setter;import javax.persistence.DiscriminatorValue;import javax.persistence.Entity;@Entity@DiscriminatorValue("B")@Getter @Setterpublic class Book extends Item{ private String author; private String isbn;}