2012-05-15 16 views
9

Mam aplikację, która używa hibernacji i jpa. Muszę dowiedzieć się, do którego db jest podłączony, aby niektóre natywne kwerendy sql i wykonać na podstawie db powiedzieć na przykład. wyrocznia i postgres. Jeśli używam czystego JDBC to jest proste, aby uzyskać metadane db ale nie wiem jak dostać się z kierownika jednostkiJak uzyskać metadane bazy danych z menedżera encji

Dzięki

Odpowiedz

4

Jako obejście można pobrać właściwości EntityManagerFactory aby uzyskać konfigurację bazy danych podstawowych , który jest specyficzny dla implementacji.

  • Hibernate: hibernate.connection.driver_class

  • EclipseLink:eclipselink.target-database Ta właściwość określa docelowej bazy danych. W twoim przypadku może mieć wartość jako Oracle lub PostgreSQL dla odpowiedniej bazy danych.

  • ogólne:javax.persistence.jdbc.driver

Na podstawie tych informacji można uzyskać w bazie aktualnie podłączony.

EntityManagerFactory emf = entityManager.getEntityManagerFactory();  
Map<String, Object> emfProperties = emf.getProperties(); 

String driverClass = (String)emfProperties.get(PROPERTY); 
//-- For PostgreSQL, it will have value "org.postgresql.Driver" 

if(driverClass.lastIndexOf("postgresql") != -1) 
    postGreSQL_DB = true; 

Uwaga:Niewiele jasne projektowania aplikacji, ale może się zdarzyć, że aplikacja jest podłączony do obu baz danych. Jeśli to możliwe, możesz spróbować oddzielić EntityManager dla każdej bazy danych, wskazując na różne jednostki trwałości w jednostce persistence.xml &.

Jeśli to nie jest przypadek & tylko jeden z nich jest podłączony w czasie, to może po prostu go zweryfikować przez entityManager.isOpen() lub emf.isOpen().

Edit:

Connection connection = entityManager.unwrap(Connection.class); 
DatabaseMetaData metaData = connection.getMetaData(); 

Teraz od tego, można uzyskać nazwę produktu bazy danych, kierowca itd

+0

Dziękuję Nayan za pomocne wskazówki. Kiedy próbuję uzyskać emf z em, nie widzę ich, więc wymyśliłem ten kod DatabaseMetaData dbmd = ((Session) entityManager.getDelegate()). Connection(). GetMetaData(); dbName = dbmd.getDatabaseProductName(); – user509755

+0

Nie wiem, ten kod jest przenośny dla serwera diff i prawidłowy sposób robienia tego, ponieważ hibernacja usunie metodę connection() z wersji 4.x. Ale na razie to zadziała dla mnie. – user509755

+0

@ user509755 Cieszę się, że okazało się pomocne. Próbowałem go z menedżerem encji, o czym wspomniałeś. Co się stało, gdy próbowałeś z menedżerem encji. Możesz opublikować to jako odpowiedź, może komuś pomóc. –

0

jeśli ktoś inny (jak ja) chce postarać się o jakieś informacje i jdbc używasz hibernacji 4.x, można spróbować w ten sposób:

import java.sql.Connection; 
import java.sql.SQLException; 
import org.hibernate.jdbc.Work; 
public class ConnectionInfo implements Work { 

public String dataBaseUrl; 
public String dataBaseProductName; 
public String driverName; 

@Override 
public void execute(Connection connection) throws SQLException { 
    dataBaseUrl = connection.getMetaData().getURL(); 
    dataBaseProductName = connection.getMetaData().getDatabaseProductName(); 
    driverName = connection.getMetaData().getDriverName(); 
} 

public String getDataBaseProductName() { 
    return dataBaseProductName; 
} 

public void setDataBaseProductName(String dataBaseProductName) { 
    this.dataBaseProductName = dataBaseProductName; 
} 

public String getDataBaseUrl() { 
    return dataBaseUrl; 
} 

public void setDataBaseUrl(String dataBaseUrl) { 
    this.dataBaseUrl = dataBaseUrl; 
} 

public String getDriverName() { 
    return driverName; 
} 

public void setDriverName(String driverName) { 
    this.driverName = driverName; 
} 
} 

Teraz możesz odzyskać swoje informacje tak:

// -- snip 
org.hibernate.ejb.EntityManagerImpl entityManagerImpl = (org.hibernate.ejb.EntityManagerImpl) genericDBAccess.getEntityManager().getDelegate(); 
    Session session = entityManagerImpl.getSession(); 
    connectionInfo = new ConnectionInfo(); 
    session.doWork(connectionInfo); 
// -- snap 

nadzieję, że pomoże! Prowadziłem szalone znajdowanie tych informacji ....

4

W Hibernate 4 można dostać infos bazy danych z kierownika jednostki z tym kodem:

org.hibernate.engine.spi.SessionImplementor sessionImp = 
    (org.hibernate.engine.spi.SessionImplementor) eManager.getDelegate(); 
DatabaseMetaData metadata = sessionImp.connection().getMetaData(); 
//do whatever you need with the metadata object... 
metadata.getDatabaseProductName(); 

Cheers

Emmanuel

+0

W nowszych wersjach pf Hibernate 3 działa również. – SkorpEN

+0

Jak uzyskać menedżera encji ('eManager')? – sakra

1

podstawie Emmanuel odpowiedzieć, jak to zrobić z wiosny i hibernacja:

@Repository 
public class UserRepository { 

    @PersistenceContext 
    private EntityManager em; 

    public void getMeta() { 
     org.hibernate.engine.spi.SessionImplementor sessionImp = (org.hibernate.engine.spi.SessionImplementor) em.getDelegate(); 
     DatabaseMetaData metadata = null; 
     try { 
      metadata = sessionImp.connection().getMetaData(); 
      ResultSet res = metadata.getColumns(null, null, "USERS", "USERNAME"); 
      System.out.println("List of columns: "); 
      while (res.next()) { 
       System.out.println(
         " " + res.getString("TABLE_SCHEM") 
           + ", " + res.getString("TABLE_NAME") 
           + ", " + res.getString("COLUMN_NAME") 
           + ", " + res.getString("TYPE_NAME") 
           + ", " + res.getInt("COLUMN_SIZE") 
           + ", " + res.getInt("NULLABLE")); 
      } 
      res.close(); 
      System.out.println(); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
Powiązane problemy