Как узнать, использует ли мой EntityManager источник данных JTA или RESOURCE_LOCAL?

У меня есть служебный класс, как показано ниже. Я хочу иметь возможность использовать этот класс либо с RESOURCE_LOCAL, либо с единицами хранения JTA. Если я изменю файл persistence.xml с JTA на RESOURCE_LOCAL, мне не придется менять код.

Я попытался использовать EntityManager.getTransaction(), чтобы увидеть, есть ли активная транзакция, но вызов getTransaction() вызывает исключение, если используется JTA. Я мог бы окружить вызов getTransaction() с помощью try/catch, но я не хочу прибегать к обработке исключений для этого. EntityManager.getProperties() не показывает ничего, что указывает на JTA или RESOURCE_LOCAL.

Мне нужно каким-то образом определить, какой тип единицы персистентности использует EntityManager (или EntityManagerFactory) в приведенном ниже коде.

public class CredentialsUtil {

public static final String VGBD_PU = "VGDBpu";
static Logger logger = Logger.getLogger(CredentialsUtilStatic.class);
static EntityManagerFactory emf = Persistence.createEntityManagerFactory(VGBD_PU);
public static final String sharedKey="pgpsympwd";



public static String getPassword(String username) {

    String selectStr = "select pgp_sym_decrypt(pgpsympassword, '" + sharedKey + "') from credentials where username='" + username + "'";

    EntityManager em =null;
    String password = "";

    try {
        em = emf.createEntityManager();

        java.util.Map<java.lang.String,java.lang.Object> propMap = em.getProperties();
        logger.info(propMap.keySet().size() + " properties");

        for (String key : propMap.keySet())
            logger.info(key + ", " + propMap.get(key));

        EntityTransaction tx = em.getTransaction(); ...

person Dean Schulze    schedule 04.11.2011    source источник


Ответы (2)


Вы можете попробовать что-то вроде этого, которое использует разные API для транзакций для двух типов менеджеров сущностей:

public boolean isResourceLocal(EntityManager em) {

  try {
    EntityTransaction tx = em.getTransaction();
    return true;
  } catch (IllegalStateException ex) {
    return false;
  }

}
person Jeff Putney    schedule 13.08.2012
comment
Начиная с JPA 2.1 вы можете использовать em.isJoinedTransaction() - person dmatej; 21.07.2016

Когда вы вызываете getTransaction() в диспетчере сущностей JTA, поставщик постоянства выдает ошибку IllegalStateException.

Подробнее см. в javadoc:

EntityTransaction getTransaction()

Возвратите объект EntityTransaction уровня ресурсов. Экземпляр EntityTransaction можно использовать последовательно для запуска и фиксации нескольких транзакций.

Возвращает: экземпляр EntityTransaction.

Выдает: IllegalStateException - если вызывается в менеджере сущностей JTA.

Когда вы используете EclipseLink, это вызывает откат текущей транзакции:

public EntityTransaction getTransaction() {
    try {
        return ((TransactionWrapper)this.transaction).getTransaction();
    } catch (RuntimeException e) {
        setRollbackOnly();
        throw e;
    }
}
person user5397644    schedule 01.10.2015