Как программно извлекать источник данных, используемый блоком персистентности

... без фактического чтения и анализа persistence.xml

Я могу получить имя единицы сохранения в EntityManager с помощью свойств этого factory. Я могу получить доступные источники данных с помощью jboss-as-controller-client. Но я не нашел API, который бы дал мне источник данных для конкретного EntityManager.

A String с именем будет достаточно.

Спасибо

Я работаю с Hibernate 4.0.1.Final над JPA 2 на JBoss 7.1.1.Final.

EDIT: и я хотел бы избежать отклонения от JPA до API Hibernate, если это возможно.

EDIT: решение Augusto работало, у меня есть некоторые примечания по деталям: литье EM не работает из-за ClassCastException: (org.jboss.as.jpa.container.TransactionScopedEntityManager cannot be cast to org.hibernate.ejb.EntityManagerImpl), но оно работало для извлеченного factory. Поэтому я опустил шаг 1.

Я также не смог найти способ получить имя источника данных из экземпляра. Поэтому мне пришлось довольствоваться именем каталога: connectionProvider.getConnection().getCatalog();

Ответ 1

Вам необходимо:

  • введите EntityManager в EntityManagerImpl (реализация Hibernate)
  • вызов getFactory()
  • введите EntityManagerFactory в HibernateEntityManagerFactory
  • вызовите getSessionFactory() и добавьте его в SessionFactoryImpl
  • вызвать getConnectionProvider() и применить его к правильной реализации. Здесь вы можете увидеть реализации здесь. Я предполагаю, что это a DatasourceConnectionProvider
  • вызов getDataSource(), и все готово.

К сожалению, вы должны использовать Hibernate API, так как нет способа получить DataSource с помощью JPA API.

Ответ 2

Если вы просто хотите, чтобы имя источника данных и это имя источника данных было поставлено на JPA, вы должны получить эту информацию с помощью:

entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.jtaDataSource" );

или

entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.nonJtaDataSource" );

в зависимости от того, как вы определили источник данных.

Ответ 3

В среде Spring вы можете использовать это:

import org.springframework.orm.jpa.EntityManagerFactoryInfo;
...

@PersistenceContext
EntityManager entityManager;

public DataSource getDataSourceFromHibernateEntityManager() {
   EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) entityManager.getEntityManagerFactory();
   return info.getDataSource();
}

Ответ 4

Мне нужно было сделать это, чтобы выполнить миграцию Flyway. Мне не удалось получить DataSource с помощью метода Augusto, но я смог восстановить источник данных, извлекая URL-адрес, имя пользователя и пароль из свойств SessionFactory:

SessionFactory sessionFactory = ((HibernateEntityManagerFactory) entityManagerFactory).getSessionFactory();
Properties properties = ((SessionFactoryImpl) sessionFactory).getProperties();
String url = (String) properties.get("hibernate.connection.url");
String username = (String) properties.get("hibernate.connection.username");
String password = (String) properties.get("hibernate.connection.password");

Ответ 5

Попробуйте следующее:

Session s = (Session) getEntityManager().getDelegate();
org.hibernate.SessionFactory sessionFactory=s.getSessionFactory();
ConnectionProvider cp=((SessionFactoryImpl)sessionFactory).getConnectionProvider();Connection connection=cp.getConnection();
DatabaseMetaData dbmetadata= connection.getMetaData();
String dtsource=dbmetadata.getUserName();

Ответ 6

Я использую Hibernate 5.0.x

Вот как я получаю соединение из пула сохраняемости:

import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;

public Connection getConnection(EntityManagerFactory emf) throws SQLException
{
    final EntityManagerFactoryImpl hibernateEmf = (EntityManagerFactoryImpl) emf;
    return hibernateEmf.getSessionFactory().getServiceRegistry().getService(ConnectionProvider.class).getConnection();
}

Параметр emf представляет собой стандарт JPA javax.persistence.EntityManagerFactory, обычно приобретаемый глобально с использованием:

emf = Persistence.createEntityManagerFactory("persistence-unit-name");

или путем инъекции:

@PersistenceUnit(unitName="persistence-unit-name")
EntityManagerFactory emf;