최대 절전 모드 일대 다 주석 자습서

1. 소개

이 빠른 Hibernate 튜토리얼은 XML의 대안 인 JPA 주석을 사용하는 일대 다 매핑 의 예 를 안내합니다.

또한 양방향 관계가 무엇인지, 어떻게 불일치를 생성 할 수 있는지, 소유권 개념이 어떻게 도움이 될 수 있는지에 대해서도 알아 봅니다.

2. 설명

간단히 말해서 일대 다 매핑은 테이블의 한 행이 다른 테이블의 여러 행에 매핑된다는 것을 의미합니다.

일대 다 연결 을보기 위해 다음 엔터티 관계 다이어그램을 살펴 보겠습니다 .

이 예에서는 각 카트에 대한 테이블과 각 항목에 대한 다른 테이블이있는 카트 시스템을 구현합니다. 하나의 카트에 많은 항목이있을 수 있으므로 여기 에 일대 다 매핑이 있습니다.

이 데이터베이스 수준에서 작동하는 방식은 우리가 가지고있다 cart_id 의 기본 키로 카트 테이블과도 cart_id 의 외부 키로 항목을 .

코드에서 우리가하는 방식은 @OneToMany 입니다.

데이터베이스의 관계를 반영하는 방식으로 Cart 클래스를 Items 객체에 매핑 해 보겠습니다 .

public class Cart { //... @OneToMany(mappedBy="cart") private Set items; //... }

@ManyToOne을 사용하여 항목의 카트 에 대한 참조를 추가 하여 양방향 관계를 만들 수도 있습니다 . 양방향은 카트 에서 항목 에 액세스 할 수 있고 항목 에서 카트 에도 액세스 할 수 있음을 의미 합니다 .

mappedBy의 속성은 우리가 우리의 자식 클래스에서 부모 클래스를 나타 내기 위해 사용하는 변수 최대 절전 모드를 얘기하는 데 사용하는 것입니다.

일대 다 연관 을 구현하는 샘플 Hibernate 애플리케이션을 개발하기 위해 다음 기술과 라이브러리가 사용됩니다 .

  • JDK 1.8 이상
  • 최대 절전 모드 5
  • Maven 3 이상
  • H2 데이터베이스

3. 설정

3.1. 데이터베이스 설정

아래는 CartItems 테이블에 대한 데이터베이스 스크립트입니다 . 일대 다 매핑에 외래 키 제약 조건을 사용합니다 .

CREATE TABLE `Cart` ( `cart_id` int(11) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`cart_id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; CREATE TABLE `Items` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `cart_id` int(11) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `cart_id` (`cart_id`), CONSTRAINT `items_ibfk_1` FOREIGN KEY (`cart_id`) REFERENCES `Cart` (`cart_id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

데이터베이스 설정이 준비되었으므로 Hibernate 예제 프로젝트를 생성 해 보겠습니다.

3.2. Maven 종속성

그런 다음 Hibernate 및 H2 드라이버 종속성을 pom.xml 파일에 추가합니다. Hibernate 종속성은 JBoss 로깅을 사용하며 자동으로 전이 종속성으로 추가됩니다.

  • Hibernate 버전 5 .2.7.Final
  • H2 드라이버 버전 1 .4.197

최신 버전의 Hibernate 및 H2 종속성에 대해서는 Maven 중앙 저장소를 방문하십시오.

3.3. Hibernate 구성

Hibernate의 구성은 다음과 같습니다.

  org.h2.Driver   jdbc:h2:mem:spring_hibernate_one_to_many sa org.hibernate.dialect.H2Dialect thread true  

3.4. HibernateAnnotationUtil 클래스

으로 HibernateAnnotationUtil의 클래스, 우리는 단지 새로운 하이버 네이트 구성 파일을 참조해야합니다

private static SessionFactory sessionFactory; private SessionFactory buildSessionFactory() { ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder(). configure("hibernate-annotation.cfg.xml").build(); Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build(); SessionFactory sessionFactory = metadata.getSessionFactoryBuilder().build(); return sessionFactory; } public SessionFactory getSessionFactory() { if(sessionFactory == null) sessionFactory = buildSessionFactory(); return sessionFactory; }

4. 모델

매핑 관련 구성은 모델 클래스에서 JPA 주석을 사용하여 수행됩니다.

@Entity @Table(name="CART") public class Cart { //... @OneToMany(mappedBy="cart") private Set items; // getters and setters }

것을 바랍니다 참고 @OneToMany의 주석에서 속성을 정의하는 데 사용됩니다 항목 지도하는 데 사용되는 클래스 mappedBy의 변수를. 이것이 바로 Items 클래스 에 " cart " 라는 속성이있는 이유입니다 .

@Entity @Table(name="ITEMS") public class Items { //... @ManyToOne @JoinColumn(name="cart_id", nullable=false) private Cart cart; public Items() {} // getters and setters } 

@ManyToOne 주석이 Cart 클래스 변수 와 연결되어 있다는 점도 중요 합니다. @JoinColumn 주석은 매핑 된 열을 참조합니다.

5. 행동

테스트 프로그램에서 우리는 Hibernate Session을 얻기위한 main () 메소드를 가진 클래스를 만들고, 일대 다 연관 구현하는 데이터베이스에 모델 객체를 저장하고 있습니다 :

sessionFactory = HibernateAnnotationUtil.getSessionFactory(); session = sessionFactory.getCurrentSession(); System.out.println("Session created"); tx = session.beginTransaction(); session.save(cart); session.save(item1); session.save(item2); tx.commit(); System.out.println("Cartitem1, Foreign Key Cartitem2, Foreign Key Cartmany-to-one">6. The @ManyToOne Annotation

As we have seen in section 2, we can specify a many-to-one relationship by using the @ManyToOne annotation. A many-to-one mapping means that many instances of this entity are mapped to one instance of another entity – many items in one cart.

The @ManyToOne annotation lets us create bidirectional relationships too. We'll cover this in detail in the next few subsections.

6.1. Inconsistencies and Ownership

Now, if Cart referenced Items, but Items didn't in turn reference Cart, our relationship would be unidirectional. The objects would also have a natural consistency.

In our case though, the relationship is bidirectional, bringing in the possibility of inconsistency.

Let's imagine a situation where a developer wants to add item1 to cart and item2 to cart2, but makes a mistake so that the references between cart2 and item2 become inconsistent:

Cart cart1 = new Cart(); Cart cart2 = new Cart(); Items item1 = new Items(cart1); Items item2 = new Items(cart2); Set itemsSet = new HashSet(); itemsSet.add(item1); itemsSet.add(item2); cart1.setItems(itemsSet); // wrong!

As shown above, item2 references cart2, whereas cart2 doesn't reference item2, and that's bad.

How should Hibernate save item2 to the database? Will item2 foreign key reference cart1 or cart2?

We resolve this ambiguity using the idea of an owning side of the relationship; references belonging to the owning side take precedence and are saved to the database.

6.2. Items as the Owning Side

As stated in the JPA specification under section 2.9, it's a good practice to mark many-to-one side as the owning side.

In other words, Items would be the owning side and Cart the inverse side, which is exactly what we did earlier.

So how did we achieve this?

By including the mappedBy attribute in the Cart class, we mark it as the inverse side.

At the same time, we also annotate the Items.cart field with @ManyToOne, making Items the owning side.

Going back to our “inconsistency” example, now Hibernate knows that the item2‘s reference is more important and will save item2‘s reference to the database.

Let's check the result:

item1 ID=1, Foreign Key Cart ID=1 item2 ID=2, Foreign Key Cart ID=2

Although cart references item2 in our snippet, item2‘s reference to cart2 is saved in the database.

6.3. Cart as the Owning Side

It's also possible to mark the one-to-many side as the owning side, and many-to-one side as the inverse side.

Although this is not a recommended practice, let's go ahead and give it a try.

The code snippet below shows the implementation of one-to-many side as the owning side:

public class ItemsOIO { // ... @ManyToOne @JoinColumn(name = "cart_id", insertable = false, updatable = false) private CartOIO cart; //.. } public class CartOIO { //.. @OneToMany @JoinColumn(name = "cart_id") // we need to duplicate the physical information private Set items; //.. } 

Notice how we removed the mappedBy element and set the many-to-one @JoinColumn as insertable and updatable to false.

If we run the same code, the result will be the opposite:

item1 ID=1, Foreign Key Cart ID=1 item2 ID=2, Foreign Key Cart ID=1

As shown above, now item2 belongs to cart.

7. Conclusion

We have seen how easy it is to implement the one-to-many relationship with the Hibernate ORM and H2 database using JPA annotations.

Additionally, we learned about bidirectional relationships and how to implement the notion of an owning side.

The source code in this article can be found over on GitHub.