작성
·
160
·
수정됨
0
@Entity
@Table(name = "orders")
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Order {
@Id
@GeneratedValue
@Column(name = "order_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
// @ManyToOne
@JoinColumn(name = "member_id")
private Member member;
@JsonIgnore
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
@JsonIgnore
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
// @OneToOne
@JoinColumn(name = "delivery_id")
private Delivery delivery;
private LocalDateTime orderDate; //주문시간
@Enumerated(EnumType.STRING)
private OrderStatus status; //주문상태 [ORDER, CANCEL]
이렇게 작성하면 보면 h2에서 필드에 작성한대로 id ||member || delivery 이렇게 나와야 하는데
저는 member || delivery ||id 이렇게 나 순서가 보장되지 않게 나옵니다.
인터넷에 찾아보니 엔티티 필드 순서가 데이터베이스의 컬럼 순서를 결정하지 않기 때문에 schema-generation.scripts.create-target을 주어야 한다고 나와있는데 해당 강의 코드를 보아도 저런 걸 설정하지 않았는데 강의에서는 어떻게 필드가 순서가 보장이 되었나요?
여기서 찾았는데요. 실무에서는 ddl을 직접입력하라는건데요. 그런데 궁금한점이 실무에서는 fechjoin이나 joincolum을 안쓰나요? ddl을 입력하는거면 joincolum(외래키)까지 같이입력하는거 아닌가요?
2. @ManyToOne 컬럼에서 조인할 때 데이터 테이블명을 기준으로 조인하고 OneToMany는 mappedBy 할 때 클래스명을 기준으로 하는것처럼 보입니다. 혹시 이유 좀 알 수 있나요? OneToMany에서 자기 자신을 바라봐서 mapped by여도 참조는 둘다 똑같이 클래스로 들어가거나 테이블명으로 들어가야 하는거 아닌가요?
3.엔티티 설계시 주의점 24분에서 질문이있습니다. 아래처럼 연관관계 메소드는 중심이 되는지점에 입력하라고 하셨는데요. member 메소드에는 왜 getOrders() 에서 add()이고 orderItem은 왜 그냥 add(orderItem);만 붙나요? 저는 orders가 리스트라서 getOrders로 붙이는 줄 알았는데 orderItems도 리스트라서요.
그리고 orderItem에서 가르키는 this는 무엇인가요? 매소드 내에서 this가 없어요. this 우선순위가 메소드 내부에 this가 있을 때 this를 지칭하고 나머지는 클래스를 지칭하는건가요?
// setMember 메서드는 Order 객체에 Member 객체를 연결하고, 역방향으로도 Member의 주문 목록에 이 Order를 추가합니다.
public void setMember(Member member) {
// 현재 Order 객체의 member 필드에 매개변수로 받은 Member 객체를 할당합니다.
this.member = member;
// Member 객체의 getOrders 메서드를 호출해 주문 목록을 가져온 뒤, 현재 Order 객체(this)를 그 목록에 추가합니다.
// 이는 Member 객체 내부의 주문 목록에도 현재 Order 객체가 포함되도록 하는 역방향 연결을 설정합니다.
member.getOrders().add(this);
}
public void addOrderItem(OrderItem orderItem) {
orderItems.add(orderItem);
orderItem.setOrder(this);
}
답변 1
0
안녕하세요. zzzzz님, 공식 서포터즈 코즈위버입니다.
네 맞습니다. 테이블 스키마를 작성할 때는 P.K, F.K도 직접 작성해야 하는데요, 이 때 컬럼 명이 엔터티에 작성한것과 일치하지 않으면 문제가 생깁니다. 엔터티의 @JoinColumn 작성한 필드명이 DDL에 동일한 이름으로 명시되어 있어야 합니다.
@JoinColum 에서 name 은 테이블의 컬럼명을 명시하게 되어 있고, @OneToMany의 mappedBy 는 엔터티의 필드명을 작성하는것이 스펙입니다. 이 부분은 혼동하기 쉬운 부분이라고 동감합니다.
이 부분은 질문을 조금더 보충해서 설명해주시길 부탁드립니다 🙂 메서드 안에서 this 는 클래스의 '인스턴스' 자신을 지칭하는 키워드 입니다.
감사합니다.
3번 추가 질문입니다.
member.getOrders().add(this);<-setMember(Member member) {부분
orderItems. add(orderItem);<-void addOrderItem(OrderItem orderItem)
왜 같은 add면서 위에는 getOrders()가 붙고 아래는 안붙어요?
슈퍼히어로 테이블이 만약 시민 테이블의 시민번호를 외래키로 참조한다고 가정하면
테이블 생성 쿼리는 아래와 같습니다.
CREATE TABLE superheroes (
hero_id BIGINT AUTOINCREMENT,
civil_id BIGINT,
이름 TEXT NOT NULL,
직업 TEXT NOT NULL,
능력 TEXT,
국적 TEXT,
소속회사 TEXT,
나이 INTEGER.
PRIMARY KEY (hero_id),
FOREIGN KEY (civil_id) REFERENCES civil(civil_id)
);
이 경우 SuperHeroes 엔터티의 설정은 다음과 같아야 합니다.
(정확한 코드는 아니고 개략적인 내용만 확인해주세요)
@Entity
public class SuperHeroes {
@Id
@Column(name = "hero_id")
private Long id
@ManyToOne(...)
@JoinColumn(name = "civil_id")
private Civil civil;
}
@Entity
public class Civil {
@Id
@Column(name = "civil_id")
private Long id;
@OneToMany(mappedBy="civil")
List<SuperHeroes> heroList = new ArrayList<>();
}
감사합니다.
ddl이 예를들어 아래처럼 이면요. 여기서 @JoinColumn이 어떻게 작성되는거에요?
CREATE TABLE superheroes ( id INTEGER PRIMARY KEY AUTOINCREMENT, 이름 TEXT NOT NULL, 직업 TEXT NOT NULL, 능력 TEXT, 국적 TEXT, 소속회사 TEXT, 나이 INTEGER );
출처: https://edder773.tistory.com/186 [개발하는 차리의 공부 일기:티스토리]