How to get database metadata from entity manager

前端 未结 6 1754
梦如初夏
梦如初夏 2021-02-07 09:00

I have an app which is using hibernate and jpa. I need to find out which db it is connected to so that some native sql query i execute based on db say for eg. oracle and postgre

相关标签:
6条回答
  • Based on Emmanuel answer how to do it with Spring and hibernate:

     @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();
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-07 09:19

    if anybody else (like me) wants to try to get some jdbc information and you are using hibernate 4.x, you might try it that way:

    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;
    }
    }
    

    Now you can retrieve your information like that:

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

    Hope that helps! I drove crazy finding this information....

    0 讨论(0)
  • 2021-02-07 09:21

    In case you want yo get the dba name from the url

    public String getDbName() throws SQLException {
        SessionImplementor sessionImp = (SessionImplementor) em.getDelegate();
        DatabaseMetaData metadata = sessionImp.connection().getMetaData(); 
    
        String dbName="";
        Pattern urlDbName = Pattern.compile("databaseName=([A-Za-z0-9\\-\\_]+)");
        Matcher m = urlDbName.matcher(metadata.getURL());
        while (m.find()) {
            dbName = m.group(1);
        }
    
        return dbName;   
    }
    
    0 讨论(0)
  • 2021-02-07 09:25

    In Hibernate 4, you can get the database infos from the entity manager with that code:

    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 讨论(0)
  • 2021-02-07 09:26

    As a workaround, you can fetch the EntityManagerFactory properties to get the underlying database configuration, which is implementation specific.

    • Hibernate : hibernate.connection.driver_class

    • EclipseLink : eclipselink.target-database This property specifies the target database. In your case, it may have value as Oracle or PostgreSQL for respective database.

    • General : javax.persistence.jdbc.driver

    From this information, you can get the database currently connected.

    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;
    

    Note : Not much clear on your application design, but it may happen that your application is connected to both the databases. If possible, you can try having separate EntityManager for each database, pointing to different persistence units in persistence.xml & can use it accordingly.

    If this is not the case & only one of them is connected at a time, then you can simply verify it by entityManager.isOpen() or emf.isOpen().

    Edit :

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

    Now from this, you can get database product name, driver etc.

    0 讨论(0)
  • 2021-02-07 09:29

    Use following line to get information related to your connection and datasource

    entityManager.getEntityManagerFactory().getProperties().get("hibernate.connection.datasource");
    
    0 讨论(0)
提交回复
热议问题