인프런 커뮤니티 질문&답변

궁금이님의 프로필 이미지

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

주문 목록 검색, 취소

jpql 엔티티 인지 오류

해결된 질문

23.11.12 00:15 작성

·

2K

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
일단은 해결 했습니다.

findAllString 이용하는데 Order를 얘가 모르는 거 같아서..

String jpql = "select o From jpabook.jpashop.domain.Order o join o.member m";

이렇게 패키지경로까지 다 명시해줬더니 인지를 하더라구요..

안 그러면

org.hibernate.query.sqm.UnknownEntityException: Could not resolve root entity 'Order'
	at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitRootEntity(SemanticQueryBuilder.java:1960) ~[hibernate-core-6.2.13.Final.jar:6.2.13.Final]
	at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitRootEntity(SemanticQueryBuilder.java:253) ~[hibernate-core-6.2.13.Final.jar:6.2.13.Final]
...............

얘가 이렇게 Order 인지 못한다고 오류가 뜹니다..

원래 엔티티는 그냥 @Entity 등록 하면 알아서 인지 되는걸로 알고 있었는데..

왜 이런 걸까요?

package jpabook.jpashop.domain;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity(name = "orders")
@Getter
@NoArgsConstructor(access = AccessLevel.PUBLIC)
public class Order {
    @Id @GeneratedValue
    @Column(name = "order_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
    private List<OrderItem> orderItems = new ArrayList<>();

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "delivery_id")
    private Delivery delivery;

    private LocalDateTime orderDate;


    @Enumerated(EnumType.STRING)
    private OrderStatus status;

    public void changeMember(Member member){
        this.member = member;
        member.getOrders().add(this);
    }

    public void addOrderItem(OrderItem orderItem){
        orderItems.add(orderItem);
        orderItem.setOrder(this);
    }

    private void setOrderDate(LocalDateTime orderDate) {
        this.orderDate = orderDate;
    }

    public void changeDelivery(Delivery delivery){
        this.delivery = delivery;
        delivery.setOrder(this);
    }

    private void setStatus(OrderStatus status) {
        this.status = status;
    }



    public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems){
        Order order = new Order();
        order.changeMember(member);
        order.changeDelivery(delivery);
        for (OrderItem orderItem : orderItems) {
            order.addOrderItem(orderItem);
        }
        order.setStatus(OrderStatus.ORDER);
        order.setOrderDate(LocalDateTime.now());
        return order;
    }

    public void cancel(){
        if(delivery.getStatus() == DeliveryStatus.COMP){
            throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다.");
        }

        this.setStatus(OrderStatus.CANCEL);
        for (OrderItem orderItem : orderItems) {
//            orderItem.getItem().removeStock(orderItem.getCount());
            orderItem.cancel();
        }
    }

    public int getTotalPrice(){
        int totalPrice = 0;
        for( OrderItem orderItem : orderItems){
            totalPrice += orderItem.getTotalPrice();
        }
        return totalPrice;
    }
}

답변 1

1

y2gcoder님의 프로필 이미지

2023. 11. 12. 14:16

안녕하세요. 궁금이님, 공식 서포터즈 y2gcoder입니다.

도움을 드리고 싶지만 질문 내용만으로는 답변을 드리기 어렵습니다.

실제 동작하는 전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx


주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요


추가로 다음 내용도 코멘트 부탁드립니다.

1. 문제 영역을 실행할 수 있는 방법

2. 문제가 어떻게 나타나는지에 대한 상세한 설명

올려주시면 코드를 확인해보겠습니다!

 

감사합니다.

궁금이님의 프로필 이미지
궁금이
질문자

2023. 11. 12. 14:40

본업도 있으신데 감사합니다!!

https://drive.google.com/file/d/1YcTnMKGdsOE2mC6u79kh2HBjJPVn0689/view?usp=sharing

링크입니다.

 

제 컴퓨터에서는 ClassNotFound 등의 오류가 아예 실행하면 스프링 환경이 부팅되면서 나올 때도 있고, 안 나올때도 있습니다.

안나올 경우 localhost:8080으로 들어가,

멤버생성, 상품생성 한다음 주문 시에 오류가 발생합니다.

여기서 나오는 오류는

Could not resolve root entity 'Order'

입니다.

 

제가 학원에서도 쉬는 시간 등을 이용하여 공부하고 있기에,

학원에 프로젝트 생성해 놓고, 집에도 프로젝트 생성해놓고,

src 폴더만 복사해 다니며 서로 덮어쓰기 하여 그로 인한 경로문제가 발생할 수도 있나..? 라고 생각하고 있습니다.

 

오류가 나는 부분은 Order 엔티티와(경로 등도 포함해서) OrderRepository의 findAllString 메소드 같습니다..

 

 

y2gcoder님의 프로필 이미지

2023. 11. 12. 15:14

열심히 공부하시는 모습 보기 좋다고 생각합니다!
보내주신 코드 살펴보았습니다!

먼저 Order 를 JPQL에서 인식하지 못하는 이유는 @Table 의 name 속성을 이용해서 테이블 이름만 변경해주신 것이 아니라 @Entity의 이름 속성을 이용해서 @Entity의 이름을 변경하셨기 때문입니다.

@Entity의 name 속성을 이용했을 때

image

@Table의 name 속성을 이용했을 때

image

강의 코드와 같이 @Table의 name 속성을 이용해주셔야 합니다. 그래야 JPQL에서도 해당 엔티티를 Order로 찾을 수 있고, table의 name은 orders로 할 수 있습니다.

그리고 애플리케이션 실행이 간헐적으로 실패하는 현상은 @SpringBootApplication 애노테이션이 달린 메인 클래스가 2개가 생기면서 문제가 발생한 것 같습니다.

조심스럽지만 제 추측으로는 원래 package를 web으로 해서 만드시고 나서 나중에 jpabook.jpashop 패키지를 만드시고 강의를 따라하신 것 같습니다. web 패키지 전체를 지워주세요!(테스트 쪽에 있는 web 패키지도 지워주시기 바랍니다. (+ application.properties 도 지워주십쇼!)

제가 한 방법이 정답인지는 모르겠으나 저는 이렇게 해결한 것 같습니다.