Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 315597

Summary: unwrap connection should never begin transaction
Product: z_Archived Reporter: Andrei Ilitchev <andrei.ilitchev>
Component: EclipselinkAssignee: Nobody - feel free to take it <nobody>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Andrei Ilitchev CLA 2010-06-03 10:17:57 EDT
EntityManagerImpl.unwrap method may begin transaction to unwrap connection:
} else if (cls.equals(java.sql.Connection.class)) {
    UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl) this.getUnitOfWork();
    if (!unitOfWork.isInTransaction()) {
        unitOfWork.beginEarlyTransaction();
        return (T) unitOfWork.getAccessor().getConnection();
    }
}

First of all, if uow's parent is ExclusiveIsolatedClientSession then the connection is alwaya available - no need to beginEarlyTransaction;

Secondly - and most important - in JTA environment with no transaction it will start a JTA transaction. It should be called only inside transaction.

I suggest something like:

} else if (cls.equals(java.sql.Connection.class)) {     
    UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl) this.getUnitOfWork();
    if(unitOfWork.getParent().isExclusiveIsolatedClientSession() {
        return (T) unitOfWork.getAccessor().getConnection();
    }
    if (checkForTransaction(false) != null && !unitOfWork.isInTransaction()) {
        unitOfWork.beginEarlyTransaction();
    }
    if(unitOfWork.isInTransaction()) {
        return (T) unitOfWork.getAccessor().getConnection();
    } else {
        return null;
    }
}
Comment 1 Andrei Ilitchev CLA 2010-06-03 10:32:35 EDT
Thirdly, currently even if unitOfWork is already in transaction then no connection returned.
Comment 2 Andrei Ilitchev CLA 2010-06-03 11:45:19 EDT
Here's a cleaned up version of the suggested patch:
} else if (cls.equals(java.sql.Connection.class)) {
    UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl) this.getUnitOfWork();
    if(unitOfWork.isInTransaction() || unitOfWork.getParent().isExclusiveIsolatedClientSession()) {
        return (T) unitOfWork.getAccessor().getConnection();
    }
    if (checkForTransaction(false) != null) { 
        unitOfWork.beginEarlyTransaction();
        return (T) unitOfWork.getAccessor().getConnection();
    }
    return null;
}
Comment 3 Andrei Ilitchev CLA 2010-06-04 16:02:00 EDT
Fixed in trunk.
Comment 4 Eclipse Webmaster CLA 2022-06-09 10:16:50 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink
Comment 5 Eclipse Webmaster CLA 2022-06-09 10:28:33 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink