http://wiki.eclipse.org/EclipseLink/Examples/JPA/Pagination

 위 내용 중 쉽게 쓸만 한 것은 아래 코드이다.
Query query = em.createQuery("SELECT e FROM Employee e ORDER BY e.lastName ASC, e.firstName ASC");
query.setFirstResult(5);
query.setMaxResults(5);
List emps = query.getResultList();

예제에는 오라클이라 되어 있는데 MySQL도 사용 가능하다.






 
설치된 Java 환경이 SE 인가 EE인가 살펴보자..

 



one-to-one 및 many-to-one일 경우
SE 환경에서는 JPA가 fetch 무시하고 EAGER로 적용해버린다. 

고로.. SE에서는 쓸모가 없다.. ;; 


http://www.java2s.com/Code/Java/JPA/CatalogJPA.htm

잘 되어 있고 코드도 어렵지 않다. 


http://www.objectdb.com/java/jpa/persistence

JPA 각 클래스 및 짤막한 예제 코드가 있는 곳. 


<01. package 생성>
src 하위에 자신만의 package를 생성한다. 

<02. Table 가져오기>
만든 패키지에서 우클릭 후 JPA Entities from Tables를 눌러 아래 화면으로 이동한다.
만약, MySQL Workbench를 이용한다면 DB 모델링을 끝마친후 DB를 생성한 다음 이 작업을 하게 되는데
모델링된 결과를 바로 Java로 가지고 올 수 있어 편하다.
 

<03. DB 접속>
프로젝트 생성시 만들었던 DB Connection을 이용해 DB내의 Table 정보를 보여준다. 
Java로 가져올 Table(Entity)를 선택한다. 

<03-1. 관계설정>
만약 Entity간의 관계가 설정이 되어 있다면 자동으로 관계를 설정해준다.
이는 Entity 설정에 의한 자동 매핑으로 Entity에 관계 설정이 없다면 단일 테이블(Entity)로 판단하고 관계를 생성하지 않는다. 

<03-2. 추가 설정>
먼저 PK 생성 방법, 늦은 로딩 등을 설정할 수가 있다. 
여기서 관계를 표현하기 위한 방법을 지정하여야 하는데, 1:N의 관계라면 N을 표현할 type을 지정해준다.
List가 편하기에 List로 설정 한 것.

만약 확장(extends)해야 할 클래스가 있따면 Superclass에 적어주면 되고
어떤 인터페이스를 구현해야 할 경우도 interfaces에 적어주면 된다.
 

<03-4. 테이블 변환 정보>
각 테이블이 자바로 변환될 때 표현될 필드와 클래스 이름을 표시해준다.
접근자와 각 컬럼(필드)별 이름을 별도 지정해 줄 수 있다. 

<04. Table을 java로 가져온 결과>
PK가 붙은 파일은 복합 키 구조일 경우 자동으로 생성되는 파일이다.

 
추가 작업은 Spring 3.1, myBatis 설정 추가와 JPA와 Spring을 이어줄 JPA Dialect를 만들어 주는 것 정도?


<01. 웹 프로젝트 생성>



<02. Project 설정>
중간에 보이는 Configuration을 바꿔주어야 한다.
여기서 그냥 Finish를 눌러서 프로젝트 정보에서도 가능하나, 만들때 하기로 한다.

Modify를 누러서 진행 

<03. JPA 설정>
JPA를 선택하고 Runtimes에 Tomcat을 선택한다. 현재 JPA Version은 2.0으로 되어 있다. 

<04. JPA Library 다운로드>
플랫폼은 EclipselInk 2.4를 사용할 것이고 해당 라이브러리는 Download 버튼을 누르면 아래처럼 창이 나온다. 

<05. Library 다운로드>
각 환경에 맞는 EclipseLink를 선택한 후 Next를 눌러 다운로드를 완료한다. 

<06. 추가 라이브러리 설정>
JPA에 필요한 Hibernate 관련 라이브러리를 추가해주어야 한다. 
다운로드 버튼 위 라이브러리 구성 화면으로 들어가 아래 화면으로 이동한다.

이 화면에서 Add External JARs로 이동해 HIbernate JAR 파일을 추가해준다.
최신 라이브러리를 넣으면 되며 라이브러리는 www.hibernate.org 에서 구할수 있다. 

<07. 라이브러리 추가>
OK를 누르고 Finish를 누른다.
06 화면에서 라이브러리 설정 아래 Connection이 있는데, MySQL로 설정을 해주자.
Add Connection을 눌러 아래 화면으로 이동한다.
 

<08. MySQL Connection 추가>
Name을 바꿔주고 Next 

<08-1. Driver 추가 및 설정>
기존에 만들어 놓은게 있어 나타나지만, 처음 만들경우 아무것도 나타나지 않는다.
Drivers 우측에 있는 + 아이콘을 눌러 추가 화면으로 이동한다. 

<08-2. DB Connection 정보 입력>
자신의 정보에 맞게 입력해준다. 

<08-3. 완료된 설정 화면>

<09. 프로젝트 생성 완료 화면>
Finish를 눌러 프로젝트 생성을 완료한다. 

Server OS : Ubuntu 10.04
MySQL : 5.5.28, for debian-linux-gnu (x86_64) using readline 6.2


MySQL 역시 샘플 DB를 제공한다.

160MB 정도의 대용량을 샘플로 제공하는데, 이를 통해 JPA 프로젝트 생성을 할 수 있다.
샘플 DB의 Table역시 각 관계가 설정되어 있어 JPA에서 관계를 어떻게 표현하는지 알 수 있기에 다른 샘플 DB보다 적합하다.

자세한 것은 아래 URL을 참조.
http://dev.mysql.com/doc/employee/en/employees-introduction.html 

MySQL Example Database download
https://launchpad.net/test-db/employees-db-1/1.0.6/+download/employees_db-full-1.0.6.tar.bz2

실행 법은 압축을 풀고 콘솔창에서 mysql -u root -p employees < employees.sql 
sql 파일 하나만으로는 불가능하다.
sql을 살펴보면 dump 내용을 복원하는 것이기 때문에 압축 파일 내의 모든 파일이 필요하다.

DB 생성 후 각 테이블을 살펴보면..

select count(dept_no) from departments  -- 9
select count(emp_no) from employees  -- 300024
select count(emp_no) from dept_emp -- 331603
select count(dept_no) from dept_manager -- 24
select count(emp_no) from salaries -- 2844047
select count(emp_no) from titles -- 443308

자료가 상당히 많아서 아주 좋다.

 

description : only one may be defined as writable all others must be specified read-only

Many To One 매핑에서 자주 발생하는 문제이다..
또한 추가적으로 One쪽 PK가 Many쪽에서도 PK로 사용된다면 JPA 초기 설정된 상태로는 100% 에러난다.

A와 B의 관계가 N:1이면 A와 B의 PK들은 아래의 구조를 가지게 된다.


	//MasterCodes.java (A와 B의 관계에선 A, 즉 Many 쪽 table)
	@EmbeddedId
	private MasterCodesPK id; //복합키

	@Column(name="CODE_NAME")
	private String codeName;

	//생략~~

	//bi-directional many-to-one association to MasterCodeGroups
	@ManyToOne(cascade = REFRESH)
	@JoinColumn(name="CODE_GROUP_SEQ")
	private MasterCodeGroups masterCodeGroup;
	
	// getter / setter 생략~
	//MasterCodeGroups.java (A와 B의 관계에선 B, 즉 One에 해당)
	@Id
	@Column(name="CODE_GROUP_SEQ")
	@GeneratedValue(generator = "MASTER_CODE_GROUPS")
	private int codeGroupSeq;

	@Column(name="CODE_GROUP_NAME")
	private String codeGroupName;

	// 생략~~

	//bi-directional many-to-one association to MasterCodes
	@OneToMany(mappedBy="masterCodeGroup", cascade = REFRESH)
	private Set masterCodes;

	// getter - setter 생략~


위 내용이 JPA로 Table에서 불러와 세팅 된 것인데 이대로 했다가 에러가 빵 뜨더라..;;
그 에러가 제목과 같은 에러인데 -
복합키로 구성될 경우 자신의 PK가 아닌 다른 Table의 PK를 변경할 수 있다면? 있을수 없는 일이다;;
즉 A와 B에서 A의 키는 A_PK, B_PK를 사용하는데 A테이블에서 B_PK를 변경할 수 있다면? 무결성이 깨지게 된다.;;
이때는 차라리 B에서 B_PK가 변경된다면 A에서도 B_PK가 변경되게 제약 조건을 설정하는게 좋다 -

그래서 read-only로 하라는 에러가 나오는 것인데 -

아래와 같이 A테이블에 설정을 더 적어 주어야 한다..


	//MasterCodes.java (A와 B의 관계에선 A, 즉 Many 쪽 table)
	@EmbeddedId
	private MasterCodesPK id; //복합키

	@Column(name="CODE_NAME")
	private String codeName;

	//생략~~

	//bi-directional many-to-one association to MasterCodeGroups
	@ManyToOne(cascade = REFRESH)
	@JoinColumn(name="CODE_GROUP_SEQ", nullable=false, insertable=false, updatable=false)
	private MasterCodeGroups masterCodeGroup;
	
	// getter / setter 생략~



아까와 동일하나 JoinColumn Annotation에 기타 속성이 잔뜩 들어갔다;; 저렇게하면 read-only가 된다.

시간이 없어서 문서를 다 읽어보지 않고 중요 부분만 읽은 후에 썼는데 -
시간 있으신 분은 아래 사이트에서 다 읽어보면 좋을 것 같다.

http://trycatchfinally.blogspot.com/2006/01/mapping-relationships-in-ejb-30.html

+ Recent posts