• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

JPA를 SpringDataJPA로 바꿀때 DB에 저장이 안됩니다.

21.02.26 01:18 작성 조회수 1.43k

0

제가 JPA1강의를 듣고 SPRING DATA JPA도 듣고 난 후 JPA1에서 JPA로 만든 예제를 SpringDataJPA로 바꾸고 싶어서 시도해봤는데요.ItemRepository, MemberRepository, OrderRepository는 아래와 같이 만들고

public interface ItemRepository extends JpaRepository<Item,Long> {

Item findItemById(Long id);

} 

public interface MemberRepository extends JpaRepository<Member, Long> {

Member findMemberById(Long id);
    @Query("select m from Member m where m.name =:name")
List<Member> findByName(@Param("name") String name);
}
public interface OrderRepository extends JpaRepository<Order,Long> {

Order findOrderById(Long id);
}

동적쿼리부분은 OrderRepositoryImpl을 만들어 OrderRepository를 implements 하는 식으로 해봤는데요
@Repository
@RequiredArgsConstructor
public class OrderRepositoryImpl implements OrderRepository {

private final EntityManager em;

public List<Order> findAllByString(OrderSearch orderSearch) { //language=JPAQL
String jpql = "select o From Order o join o.member m"; boolean isFirstCondition = true;

if (orderSearch.getOrderStatus() != null) {
if (isFirstCondition) {
jpql += " where";
isFirstCondition = false;
} else {
jpql += " and";
}
jpql += " o.status = :status";
}
//회원 이름 검색
if (StringUtils.hasText(orderSearch.getMemberName())) {
if (isFirstCondition) {
jpql += " where";
isFirstCondition = false;
} else {
jpql += " and";
}
jpql += " m.name like :name";
}
TypedQuery<Order> query = em.createQuery(jpql, Order.class)
.setMaxResults(1000); //최대 1000
if(orderSearch.getOrderStatus()!=null)

{
query = query.setParameter("status", orderSearch.getOrderStatus());
}
if(StringUtils.hasText(orderSearch.getMemberName()))

{
query = query.setParameter("name", orderSearch.getMemberName());
}
return query.getResultList();
}
@Override
......
@Override
......
}



그리고 나서 ItemService, MemberService, OrderService를 밑에 처럼 작성하였고
@Service
@Transactional(readOnly=true)
@RequiredArgsConstructor
public class ItemService {

private final ItemRepository itemRepository;

@Transactional
public void saveItem(Item item){
itemRepository.save(item);
}

@Transactional
public void updateItem(Long itemId, String name, int price, int stockQuantity){
Item findItem = itemRepository.findItemById(itemId);
findItem.setName(name);
findItem.setPrice(price);
findItem.setStockQuantity(stockQuantity);

}

public List<Item> findItems(){
return itemRepository.findAll();
}

public Item findOne(Long itemId){
return itemRepository.findItemById(itemId);
}
}
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {

private final MemberRepository memberRepository;

//회원가입
@Transactional
public Long join(Member member){

validateDuplicateMember(member);
Member savedMember = memberRepository.save(member);
return savedMember.getId();
}
// 중복회원 검증
private void validateDuplicateMember(Member member) {
List<Member> findMembers = memberRepository.findByName(member.getName());
if(!findMembers.isEmpty()){
throw new IllegalStateException("이미 존재하는 회원입니다!");
}
}

// 회원 전체 조회
public List<Member> findAllMember(){
return memberRepository.findAll();
}
// 회원 조회
public Member findMember(Long id){
return memberRepository.findMemberById(id);
}
}

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OrderService {

private final OrderRepositoryImpl orderRepositoryImpl;
private final MemberRepository memberRepository;
private final ItemRepository itemRepository;

//상품 주문
@Transactional
public Long order(Long memberId, Long itemId, int count){

//엔티티 조회
Member member = memberRepository.findMemberById(memberId);
Item item = itemRepository.findItemById(itemId);

//배송정보 생성
Delivery delivery = new Delivery();
delivery.setAddress(member.getAddress());

//주문 상품 생성
OrderItem orderItem = OrderItem.createOrderItem(item, item.getPrice(), count);

//주문 생성
Order order = Order.createOrder(member, delivery, orderItem);

//주문 저장
orderRepositoryImpl.save(order);

return order.getId();
}
//상품 취소
@Transactional
public void cancelOrder(Long orderId){
Order order = orderRepositoryImpl.findOrderById(orderId);
order.cancel();
}
// 상품 조회
public Order findOne(Long orderId){
return orderRepositoryImpl.findOrderById(orderId);
}
//
public List<Order> findOrders(OrderSearch orderSearch) {
return orderRepositoryImpl.findAllByString(orderSearch);
}
}



실행을 하였을 때 회원가입과 상품등록을 하면 DB에 Member와 Item은 저장이 되지만 상품 주문을 하면 Order와 OrderItem에는
아래와 같이 아무런 정보도 저장되지 않습니다.




뭐가 틀린걸까 하고 엔티티들을 다시 작성해보고 html문서들도 다시 작성해보았는데도 아무런 이상이 없었고
Spring Data jpa를 jpa로 다시 바꾸고 나니까 DB에 Order와 OrderItem들이 저장되었습니다.
제가 Spring Data Jpa를 어떤식으로 잘못 쓴건가요?



그리고 또 하나 질문이 있는데요
위에 MemberRepository를 보시면 Member findMemberById(Long id);
이런식으로 스프링데이터jpa안에 메소드를 만들고
MemberService의
회원조회를


public Member findMember(Long id){
       return memberRepository.findMemberById(id);
}


이렇게 적었는데


MemberRepsitory에서 Member findMemberById(Long id) 메소드를 지우고 
MemberService의 회원조회에서
public Member findMember(Long id){
return memberRepository.findById(id).orElse(null);
}


이런식으로 orElse(null)을 써도 되는건가요??

답변 4

·

답변을 작성해보세요.

1

윤현식님의 프로필

윤현식

질문자

2021.02.28

해결했습니다!! 제가 사용자 정의 Repository 구현을 제대로 숙지하지 못하고 있었네요 ㅜㅜㅜ 해결해주셔서 정말 정말 감사합니다!!!:)

0

안녕하세요. 현식님

스프링 데이터 JPA를 사용하면 먼저 OrderRepositoryImpl 자체를 완전히 제거해야 합니다.

이 코드에 save 부분이 null이기 때문에 아무것도 진행되지 않습니다.

@Repository
@RequiredArgsConstructor
public class OrderRepositoryImpl implements OrderRepository {

private final EntityManager em;

@Override
public <S extends Order> S save(S entity) {
return null;
}

OrderRepositoryImpl를 완전히 제거하고 데이터 JPA에서 학습한 것 처럼 인터페이스를 주입해서 사용해주세요.

다음 부분 처럼 OrderRepositoryImpl 대신에 OrderRepository 인터페이스를 사용해주세요.

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OrderService {

// private final OrderRepositoryImpl orderRepositoryImpl;
private final OrderRepository orderRepository;

그리고 다음 메서드가 처리가 안될 것인데요.

orderRepository.findAllByString(...)

custom 스프링 데이터 JPA에서 학습한 리포지토리로 처리해주시면 됩니다.

감사합니다.

0

윤현식님의 프로필

윤현식

질문자

2021.02.27

메일 보냈습니다!!

0

안녕하세요. 윤현식님

스프링 데이터 JPA로 변경하기 전의 코드와 변경한 후의 코드를 모두 보내주세요.

zipkyh@naver.com

메일 보내주실 때는 인프런 질문 링크와

해당 케이스를 어떻게 실행할 수 있는지 자세한 설명도 부탁드립니다.

두번째 질문하신 부분은 그렇게 사용하셔도 됩니다.

감사합니다.