2012-10-05 2 views
3

스프링 @Transactional 주석에 대한 오해가 있으며 계속 유지됩니다. 나는 JPA와 Hibernate와 함께 Spring 3.1을 사용하고있다. 나는 지속성 컨텍스트에 엔티티를 추가한다는 것을 의미한다고 생각했지만 (커밋 또는 플러시 될 때까지는 어떤 쿼리도 실행하지 않음), 그리고 @Transactional 주석은 트랜잭션과 함께 메소드를 랩핑하는 것을 의미한다고 생각했습니다.Spring 트랜잭션 주석, 최대 절전 모드 및 지속성

그러나이 짧은 예제에서 실행 포인터가 지속되면 이름이 null 일 수 없으므로 예외가 발생하여 실패합니다 (db 제약 조건). 내가 setName()persist()를 교환하는 경우

import javax.persistence.EntityManager; 

@PersistenceContext 
private EntityManager entityManager; 

@Transactional 
public void test() { 
    Brand brand = new Brand(); 
    entityManager.persist(brand); 
    brand.setName("test"); 
} 

, 모든 작동합니다. 그러나, 나는 왜 어떤 쿼리가 메서드의 끝에 구축되고 실행될 것이라고 생각했기 때문에 다른 방법으로는 이해할 수 없다.

누군가가 설명시겠습니까?

답변

4

JPA에서 객체가 persist()에 전달되면 관리되는 JPA 구현의 일부로 "관리되는"것이되고 영구 객체의 ID를 생성해야합니다.

id 생성이 자동 증가 (GenerationType.IDENTITY)를 기반으로하는 경우 키를 가져오고 할당하려면 insert 문을 db에 발행해야합니다. id 생성이 시퀀스/테이블을 기반으로하는 경우 ID는 JPA 구현 관리 ID 풀에서 관리되고 할당되며이 경우 직선 삽입은 요구 사항이 아닙니다.

개체가 persist()로 전달되어 관리되면 해당 변경 사항은 트랜잭션의 및 트랜잭션에서 영구 필드가 데이터베이스로 플러시되어야합니다. ID 생성이 ID이면 삽입 후 업데이트를 따라야합니다. id 생성이 다른 방법 일 경우, 하나의 insert 문으로 충분합니다. 트랜잭션이 롤백되면 SQL을 데이터베이스에 보내지 않아야합니다.

이 구현은 Batoo JPA입니다.

희망적입니다.

+0

재미 있고, 이해가 가는데, 이제는 이해할 수 있습니다. 실제로 GenerationType.IDENTITY가 있습니다. 감사 – stivlo

2

은 트랜잭션 주석 덕분에 끝납니다. 그러나 새 레코드는 지속성에 만들어지며 예외가 발생할 수 있습니다.

메소드가 끝나기 전에 롤백 할 수 있습니다. 나는 보통 예외를 위해 롤백으로 주석을 붙인다.

0

persist는 "insert"쿼리를 실행합니다. 트랜잭션 어노테이션은 트랜잭션을 시작하기위한 것이며, 예외가 발생하면 트랜잭션을 롤백합니다.

관련 문제