Как программно извлекать источник данных, используемый блоком персистентности
... без фактического чтения и анализа 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;