2012-11-21 2 views
5

그래서 몇 가지 추가 JPA 작업으로 업데이트해야하는 기존 JDBC 호출이있는 응용 프로그램이 있습니다. 동일한 DB 트랜잭션의 일부로 JDBC 호출과 JPA 호출을 모두 수행 할 수 있어야합니다. 중요한 경우 OpenJPA 2.1.1 및 Postgres 9.1을 사용하고 있습니다. 다음 코드는 올바르게 작동합니다. 몇 가지 기본 테스트를 실행했으며 JDBC 및 JPA 문을 모두 실행합니다. 둘 중 하나의 오류로 인해 한 쌍의 명령문이 발생하지 않습니다 (예 : 동일한 DB 트랜잭션의 일부 임). 거기에 어떤 문제가있어 보이지 않는거야 - 내가 위반하는 몇 가지 모범 사례 또는 다른 방식으로 Connection 개체를이 방식으로 다시 사용할 수없는 이유가 무엇입니까?하나의 트랜잭션에서 JPA와 JDBC 작업 결합

EntityManager em = _em; //acquired from OpenJPA 
em.getTransaction().begin(); 
Connection conn; 
try { 
    OpenJPAEntityManager oem = (OpenJPAEntityManager) em.getDelegate(); 
    conn = oem.getConnection(); 
    PreparedStatement ps = conn.prepareStatement(myStatement); 
    //initialize parameters in ps 
    ps.executeUpdate(); 
    em.merge(myJpaObject); 
    em.getTransaction().commit(); 
} finally { 
    if (ps != null && !ps.isClosed()) { 
     ps.close(); 
    } 
    if (em.getTransaction().isActive()) { 
    em.getTransaction().rollback(); 
    } 
} 

감사합니다!

+0

둘 다 동일한 연결 개체를 공유하는 한 (코드를 보면 내가 생각하는 것처럼) 동일한 트랜잭션에 참여할 수 있습니다. 질문을 게시하는 대신 간단한 테스트를 작성하여이 사실을 확인하는 이유는 무엇입니까? –

+1

제 질문을 적절히 편집합니다. - 제대로 작동하는 것으로 보입니다. (실제 코드로 테스트 해봤는데 제대로 작동하는 것 같습니다.) 저는 JPA/JDBC/데이터베이스를 처음 접했을뿐입니다. 제 관심은 저의 간단한 테스트 케이스에서는 나타나지 않는 미묘한 문제가 있다는 것입니다. – Sbodd

답변

3

하나의 조정으로 나는 괜찮다고 생각합니다.

what the OpenJPA documentation has to say about it 주목할 필요가 :

반환 된 연결은 다른 EntityManager의 작업과 트랜잭션 일관성을 보장

EntityManager를 관리 대상 또는 비 낙관적 거래 인 경우, EntityManager를 현재에 플러시 경우 트랜잭션 또는 OpenJPAEntityManager.beginStore 메소드를 사용하여 데이터 스토어 트랜잭션이 진행 중인지 확인하십시오. 다른 EntityManager 조작을 시도하기 전에 항상 리턴 된 연결을 닫으십시오. OpenJPA는 데이터 스토어 트랜잭션이 진행 중일 때 기본 네이티브 연결이 해제되지 않도록합니다.

귀하의 트랜잭션은 관리되지 않지만, 나는 낙관적이지 않습니다. 또한 트랜잭션 시작과 JDBC 작업을 수행하는 사이에 JPA 작업을 수행하지 않았으므로 EntityManager가 현재 트랜잭션에서 플러시 된 경우에 해당한다고 생각합니다.

JPA로 수행하기 전에 연결을 닫는 것이 좋습니다. 나는 OpenJPA가 실제로 사용하고있는 연결을 리턴하지 않는다고 가정하지만, OpenJPA가 다시 시작되기 전에 닫혀 져야하는 랩퍼가있다.

+0

감사합니다. 그게 정확히 제가 찾던 피드백의 종류입니다! – Sbodd

관련 문제