/ SPRING BOOT, SPRING, JPA

JPA OneToOne 실습

스프링 목록

스프링 부트 목록




[프로젝트 테이블]

테이블

[문제점]

project(부모)는

project_change(자식)의 식별관계(PK + FK)이고 , 일대일 관계 이기 때문에

DB설계대로 JPA를 구현 할려면 양방향으로 만들어야 했다.

따라서, 양방향으로 연결 시 주의해야할 점들이 생겨났다.



[양방향으로 설정한 이유 (mappedBy)]

  • 관계의 주인 = 상대를 내 테이블에 fk로 참조 해버려서 (자식, 주인 이됨)
    부모의 데이터를 삭제하고 싶으면 , 자식을 먼저 삭제해줘야 한다.




A.부모(project)에서 자식(project_change) 단방향 ( x )

project에 project_change_no컬럼 이 생겨버림으로( 부모가 자식을 FK로 들고있는 상태 )

기존에 설계한 project_change 의 주키 project_no(PK, FK)가 무의미해 진다.




B.자식(project_change)에서 부모(project) 단방향 ( x )

@OneToOne에서 자식 테이블에 FK를 저장하는 단방향 관계는 JPA에서 지원하지 않는다.
출처: https://ict-nroo.tistory.com/126 [개발자의 기록습관]

project_change Entitiy에서 부모를 멤버변수로 가지고 다니는 단방향 방식을 지원 안 한다.



C. 부모가 관계의 주인인 양방향 ( x )

( project가 컬럼에 자식을 들고 다님)

@OneToOne(mappedBy = “project_change”)

이 방법 역시 기존에 설계한 project_change의 주키 project_no(PK, FK)가 무의미해 진다.




D.자식이 관계의 주인인 양방향 ( ㅇ)

( project_change가 컬럼에 부모를 들고 다님)

이 방법이 기존에 설계한 DB의 구성과 부합한다. @Id 어노테이션을 달아주면 FK,PK로 사용 할 수 있다.






[실제 코드]


project.java


@Entity
@Table(name = "project")
public class Project {
	@Id //시퀀스 설정해줘야함
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int		projectNo     ;   
	private String	longTitle     ;   
	private String	projectBrief  ;   
	private String	editorPick    ;   
	private String	projectImage  ;   
	private int		targetPrice   ;   
	private Date	startDate     ;   
	private Date	endDate       ;   
	private String	shortTitle    ;   
	private String	projectContent;   
	private String	projectUrl    ;   

	//좋아요 상태 (로그인 유저가 이프로젝트가 좋아요 일시 true)
	@Transient
	private boolean loginedUserProjectInterest=false; 



	//JOINED TABLE
	@OneToOne(mappedBy = "project",
			  cascade = CascadeType.ALL)
			  //,fetch = FetchType.EAGER)  
	//저장 시 projectChange에 setProject해야함(관계의 주인 ProjectChange)
	private ProjectChange projectChange;

	@ManyToOne
	@JoinColumn(name = "category_no")
	private Category category;

	@ManyToOne
	@JoinColumn(name = "user_no")
	private Customer maker;
	
	@OneToMany(mappedBy = "project")
	//저장 시 Reward에 setProject해야함
	//프로젝트 삭제시 리워드도 자동삭제
	private List<Reward> reward;
	                                  




projectChange.java

@MpasId 쓰는 이유 (링크)


@Entity
@Table(name = "project_change")
public class ProjectChange {
	
	@Id
	private int projectNo;
	
	@MapsId
	@OneToOne
	@JoinColumn(name = "project_no")
	private Project	project;

	private int		supportCnt;
	private String	projectStatus;
	private int		sumPrice;
	private int		projectLikeCnt;