@OrderColumn 주석을 사용할 수 있습니다.
공공 @interface의 OrderColumn
는 목록의 지속적인 질서를 유지 에 사용되는 열을 지정합니다. 지속성 공급자는 이며 검색시 주문을 유지 관리하고 데이터베이스는 입니다. 지속성 공급자는 삽입을 반영하기 위해 데이터베이스로 플러시 할 때 순서를 업데이트하고 목록에 영향을주는 삭제 또는 순서 변경을 업데이트해야합니다.
OrderColumn 주석은 OneToMany 또는 ManyToMany 관계 또는 요소 컬렉션에 지정됩니다.OrderColumn 주석 은 주문할 콜렉션을 참조하는 관계의 측면에서 지정됩니다. 주문 열은 개체 또는 embeddable 클래스 상태의 일부로 표시되지 않습니다.
OrderBy 주석은 지속 상태로 표시되고 응용 프로그램에 의해 유지 관리되는 주문에 사용해야합니다. OrderBy Annotation은 OrderColumn이 지정된 경우 사용되지 않습니다.
주문 열은 필수 유형이어야합니다. 지속성 공급자 은 연관 또는 요소 컬렉션을 업데이트 할 때 주문 열의 값을 연속적으로 (비 희소하게) 정렬합니다.
@Entity
@Table(name="STUDENT")
@SequenceGenerator(name="student_seq", initialValue=1,
allocationSize=10,sequenceName="STUDDENT_SEQ")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="student_seq")
private Long Id;
@Column(name="NAME")
private String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy="student")
@OrderColumn(name="FOLLOWUP_NUMBER")
private List<Book> books = new ArrayList<>();
...............
...............
}
: 첫 번째 요소의 위해 열 값 유일한 단점은 첫번째 요소의 수가 1
예시되지 0 있다는 0
인
@Entity
@SequenceGenerator(name="book_seq", initialValue=1,
allocationSize=10, sequenceName="BOOK_SEQ")
public class Book {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="book_seq")
private Long id;
@ManyToOne
@JoinColumn(name="STUDENT_ID")
private Student student;
@Column(name="TITLE", nullable=false)
private String title;
..................
..................
}
,210
그리고이 간단한 테스트 케이스 :
EntityTransaction tr = em.getTransaction();
tr.begin();
for (int j = 1; j < 10; j++) {
Student student = new Student("Student name " + j);
for (int i = 1; i <= 10; i++) {
student.getBooks().add(new Book("Some book" + i, student));
}
em.persist(student);
}
tr.commit();
는 다음과 같은 테이블을 생성 (오라클 12C 테스트 5.2 최대 절전 모드) :
select * from student;
ID NAME
----- --------------------
1 Student name 1
2 Student name 2
3 Student name 3
4 Student name 4
.......
.......
select * from book
order by student_id, followup_number;
ID TITLE STUDENT_ID FOLLOWUP_NUMBER
----- -------------------- ---------- ---------------
1 Some book1 1 0
2 Some book2 1 1
3 Some book3 1 2
4 Some book4 1 3
5 Some book5 1 4
6 Some book6 1 5
7 Some book7 1 6
8 Some book8 1 7
9 Some book9 1 8
10 Some book10 1 9
11 Some book1 2 0
12 Some book2 2 1
13 Some book3 2 2
14 Some book4 2 3
15 Some book5 2 4
16 Some book6 2 5
17 Some book7 2 6
18 Some book8 2 7
19 Some book9 2 8
20 Some book10 2 9
21 Some book1 3 0
22 Some book2 3 1
23 Some book3 3 2
........
........
는 성능이있을 수 있습니다 또 다른 단점은, 각 책에 대해 Hibernate가 두개의 SQL 명령을 생성했기 때문이다 - 하나의 insert와 o FOLLOWUP_NUMBER
컬럼의 업데이트.
어떤 책이 삭제되면 Hibernate는 주어진 학생의 모든 숫자를 다시 생성하고 남아있는 모든 책에 대해 FOLLOWUP_NUMBER
열의 업데이트를 실행합니다.
편집
하지만 날 귀찮게하는 것은 "순서 열이 엔티티 또는 임베드 클래스의 상태의 일부로 볼 수 없습니다."입니다. 데이터는 마치 DB 에서처럼 을 좋아하지만 내 엔티티에 반영되지 않습니다.나는 이것이 JPA에 possibe 경우
내가 모르는이 FOLLOWUP_NUMBER을 활용하고자 싶지만, 최대 절전 모드 확장 @Formula
이 경우에 사용할 수 있지만 :
class Book{
.......
.......
@Formula(value="FOLLOWUP_NUMBER")
private Long followUpNumber;
public Long getFollowUpNumber() {
return followUpNumber;
}
........
........
}
이를 다음 결과
Query query = em.createQuery(
"Select b FROM Book b JOIN b.student s " +
"WHERE s.name = :studentname AND b.followUpNumber = :follownbr"
);
query.setParameter("studentname", "Student name 6");
query.setParameter("follownbr", Long.valueOf(4));
Book book = (Book)query.getSingleResult();
System.out.println("Found book = " + book.getTitle());
System.out.println("book follow nbr= " + book.getFollowUpNumber());
제공합니다 :
계산 필드에도, 예를 들면, 아래의 테스트 케이스를 조회 할 수있다 17,451,515,
Found book = Some book5
book follow nbr= 4
및 최대 절전 모드가 그 책 찾기 위해 아래의 SQL을 사용하여 삽입에
select
book0_.id as id1_0_,
book0_.STUDENT_ID as STUDENT_ID3_0_,
book0_.TITLE as TITLE2_0_,
book0_.FOLLOWUP_NUMBER as formula0_
from
Book book0_
inner join
STUDENT student1_
on book0_.STUDENT_ID=student1_.Id
where
student1_.NAME=?
and book0_.FOLLOWUP_NUMBER=?
데이터베이스 트리거가 마음에 온다, 그것은 JPA에 의해 해결 될 필요가 없습니다. 그러나 나는 JPA 지향 솔루션을보고 싶어 할 것입니다. – Gimby