# SQLException fangen beim verbinden mit Hibernate



## F4llen4ngel (15. Jul 2009)

Einen wunderschönen ...

Möchte gern eine DB Verbindung per Hibernate aufbauen.
Klappt auch wunderbar, so lange ich die richtigen Werte eingebe.

Wenn ein Anwender falsche Daten angegeben hat, möchte ich ihn gern darauf hinweisen,
doch leider wird an der Stelle wo es kracht die jeweilige Exception schon irgendwo anders abgefangen und ausgegeben ...

Bei falschen Daten tritt der Fehler in der letzten Zeile von volgendem Code auf:


```
AnnotationConfiguration lConfiguration = buildConfiguration();
lConfiguration.configure();

mSessionFactory = lConfiguration.buildSessionFactory();
```

In der Console bekomme ich z.B. folgenden Fehler ausgegeben:


> 2009-07-15 21:27:06,355 [main] ERROR org.hibernate.tool.hbm2ddl.SchemaUpdate - could not complete schema update
> java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)



Leider komme ich mit einem try / catch Block nicht an die jeweilige Exception heran, so dass ich dem User eine Meldung ausgeben kann.

Hat jemand eine Idee wie ich an die Exception rankomme bzw. im schlimmsten Fall danach prüfen kann ob mit der Verbindung alles IO ist?


----------



## woezelmann (24. Jul 2009)

An die Exception wirst du nicht rankommen, weil sie schon von Hibernate behandelt und gelogged wird. Ich geh aber stark davon aus, dass 
	
	
	
	





```
lConfiguration.buildSessionFactory();
```
 null liefert, wenn was schiefläuft. Das kannst du dann prüfen und ggf. auch noch nen Fehler ausgeben


----------



## byte (24. Jul 2009)

Hibernate fängt die SQLException und wirft eine Hibernate Exception weiter. Diese kannst Du fangen. Du kannst Dir dann die eigentliche SQLException aus dieser Exception wieder rausholen. Einfach mal den Root Cause durchforsten.


----------



## -MacNuke- (10. Aug 2009)

byte hat gesagt.:


> Hibernate fängt die SQLException und wirft eine Hibernate Exception weiter. Diese kannst Du fangen. Du kannst Dir dann die eigentliche SQLException aus dieser Exception wieder rausholen. Einfach mal den Root Cause durchforsten.



Das ist übrigens nicht der Fall. Hibernate verschluckt die Exception (habe im Code nachgesehen). Ich habe nämlich gerade das gleiche Problem (und per Suchfunktion den Thread gefunden). Man kommt somit nicht mal an die Fehlermeldung heran, da Hibernate diese an das Logging-Framework schickt, und das war's dann.

Somit musste ich jetzt selbst eine Verbindung zur Datenbank herstellen (über DriverManager) um eine etwaige Fehlermeldung zu bekommen.

Kennt jemand sonst noch eine Lösung, außer ein anderes ORM-Framework zu nutzen?


----------



## byte (10. Aug 2009)

Ich kann Dir mit Sicherheit sagen, dass Hibernate SQL Exceptions lediglich wrapt und nicht verschluckt.

Du loggst sicher nicht den gesamten Stack Trace der Exception. Dann siehst Du solche Details natürlich nicht. Du kannst Dir ohne weiteres einen eigenen Exception Handler schreiben, der die Hibernate Exceptions auseinander nimmt und sich die tatsächliche SQL Exception rausholt. Diese kannst Du dann gezielt behandeln, falls das gewünscht ist.


----------



## -MacNuke- (10. Aug 2009)

byte hat gesagt.:


> Ich kann Dir mit Sicherheit sagen, dass Hibernate SQL Exceptions lediglich wrapt und nicht verschluckt.



Ich kann dir gerne auch den Ausschnitt aus dem Source-Code zeigen wenn du magst  Hibernate verschluckt sie  Ich habe sogar allgemein "Exception" abgefangen. Da kommt nix. Moment, ich suche sie gleich noch mal...


----------



## maki (10. Aug 2009)

-MacNuke- hat gesagt.:


> Ich kann dir gerne auch den Ausschnitt aus dem Source-Code zeigen wenn du magst  Hibernate verschluckt sie  Ich habe sogar allgemein "Exception" abgefangen. Da kommt nix. Moment, ich suche sie gleich noch mal...


Ich mag! 

Wäre nämlich etwas ganz neues wenn Hibernate Exceptions verschluckt


----------



## -MacNuke- (10. Aug 2009)

So, dann hier ganz was neues 

Auszug aus SettingsFactory.java

```
public Settings buildSettings(Properties props) {
...
				Connection conn = connections.getConnection();
				try {
					DatabaseMetaData meta = conn.getMetaData();
					log.info( "RDBMS: " + meta.getDatabaseProductName() + ", version: " + meta.getDatabaseProductVersion() );
					log.info( "JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );

					dialect = DialectFactory.buildDialect( props, conn );

					metaSupportsScrollable = meta.supportsResultSetType( ResultSet.TYPE_SCROLL_INSENSITIVE );
					metaSupportsBatchUpdates = meta.supportsBatchUpdates();
					metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit();
					metaReportsDDLInTxnSupported = !meta.dataDefinitionIgnoredInTransactions();
					metaSupportsGetGeneratedKeys = meta.supportsGetGeneratedKeys();
				}
				catch ( SQLException sqle ) {
					log.warn( "Could not obtain connection metadata", sqle );
				}
				finally {
					connections.closeConnection( conn );
				}

...
}
```


----------



## maki (10. Aug 2009)

> So, dann hier ganz was neues


Nee, da hast du etwas verwechselt 

Da geht es rein um die  MEtadaten, die Connection besteht zu diesem Zeitpunkt schon, oder eben nicht,dann ist aber schon vorher die Exception geflogen.


----------



## -MacNuke- (10. Aug 2009)

Ich bin doch nicht blöd 

Aufruf mit falschen Login-Daten

```
try {
  EntityManager em = EntityManagerUtil.getSessionFactory().createEntityManager();
  em.close();
} catch (Exception e) {
   System.out.println("Mööööööp");
}
```

Rate mal was nicht erscheint


----------



## maki (10. Aug 2009)

> Rate mal was nicht erscheint


Ein Elefant im rosa Tutu der Schwanensee tanzt? 

Mal ernsthaft, kein "Mööööööp"?


----------



## byte (10. Aug 2009)

Und wie kriegt der TE dann die SQL Exception in der Konsole, wenn Hibernate die offenbar verschluckt? :autsch:


```
2009-07-15 21:27:06,355 [main] ERROR org.hibernate.tool.hbm2ddl.SchemaUpdate - could not complete schema update
java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
```

Ich benutze Hibernate seit mehreren Jahren und habe schon diverse SQLExceptions aus dem Stacktrace gefischt.


----------



## -MacNuke- (10. Aug 2009)

maki hat gesagt.:


> Mal ernsthaft, kein "Mööööööp"?



Nein. Und der EntityManagerUtil sieht so aus:


```
public class EntityManagerUtil {
    private static EntityManagerFactory sessionFactory;

    public static EntityManagerFactory getSessionFactory() {
        if(sessionFactory == null) {
            UserLogin user = UserLogin.getInstance();

            Map<String,String> login = new HashMap<String,String>();

            //TODO: im Prinzip muessen alle Werte per Code setzbar sein
            //Implementieren einer Vorgaben-Tabelle
            login.put("hibernate.connection.url", user.getDatebaseURL());
            login.put("hibernate.connection.username", user.getUsername());
            login.put("hibernate.connection.password", user.getPassword());

            sessionFactory=Persistence.createEntityManagerFactory("axdata",login);
        }
        return sessionFactory;
    }

    public static void shutdown() {
        getSessionFactory().close();
    }
}
```

Output:

```
...
org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
12:14:58,947 -  INFO - DriverManagerConnectionProvider:64 - Using Hibernate built-in connection pool (not for production use!)
12:14:58,947 -  INFO - DriverManagerConnectionProvider:65 - Hibernate connection pool size: 20
12:14:58,947 -  INFO - DriverManagerConnectionProvider:68 - autocommit mode: true
12:14:58,974 -  INFO - DriverManagerConnectionProvider:103 - using driver: org.postgresql.Driver at URL: jdbc:postgresql://192.168.11.24/finxdb
12:14:58,975 -  INFO - DriverManagerConnectionProvider:109 - connection properties: {user=matti, password=****, autocommit=true, release_mode=auto}
12:14:59,031 -  WARN - SettingsFactory:133 - Could not obtain connection to query metadata
org.postgresql.util.PSQLException: FATAL: Passwort-Authentifizierung f��r Benutzer ��matti�� fehlgeschlagen
        at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:276)
        at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:95)
        at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
        at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:124)
        at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:30)
        at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:29)
        at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24)
        at org.postgresql.Driver.makeConnection(Driver.java:386)
        at org.postgresql.Driver.connect(Driver.java:260)
        at java.sql.DriverManager.getConnection(DriverManager.java:582)
        at java.sql.DriverManager.getConnection(DriverManager.java:154)
        at org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:133)
        at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:111)
        at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2119)
        at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2115)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1339)
        at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
        at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:52)
        at com.rutech.AuftraX.persistence.EntityManagerUtil.getSessionFactory(EntityManagerUtil.java:34)
        at com.rutech.AuftraX.App.main(App.java:125)
12:14:59,091 -  INFO - Dialect:175 - Using dialect: org.hibernate.dialect.PostgreSQLDialect
12:14:59,096 -  INFO - TransactionFactoryFactory:62 - Transaction strategy: org.hibernate.transaction.JDBCTransactionFactory
12:14:59,100 -  INFO - TransactionManagerLookupFactory:80 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
12:14:59,101 -  INFO - SettingsFactory:161 - Automatic flush during beforeCompletion(): disabled
12:14:59,102 -  INFO - SettingsFactory:165 - Automatic session close at end of transaction: disabled
12:14:59,164 -  INFO - SettingsFactory:180 - Scrollable result sets: disabled
12:14:59,165 -  INFO - SettingsFactory:188 - JDBC3 getGeneratedKeys(): disabled
12:14:59,165 -  INFO - SettingsFactory:196 - Connection release mode: auto
12:14:59,167 -  INFO - SettingsFactory:220 - Maximum outer join fetch depth: 3
12:14:59,186 -  INFO - SettingsFactory:223 - Default batch fetch size: 1
12:14:59,186 -  INFO - SettingsFactory:227 - Generate SQL with comments: disabled
12:14:59,187 -  INFO - SettingsFactory:231 - Order SQL updates by primary key: disabled
12:14:59,187 -  INFO - SettingsFactory:235 - Order SQL inserts for batching: disabled
12:14:59,187 -  INFO - SettingsFactory:397 - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
12:14:59,190 -  INFO - ASTQueryTranslatorFactory:47 - Using ASTQueryTranslatorFactory
12:14:59,190 -  INFO - SettingsFactory:243 - Query language substitutions: {}
12:14:59,191 -  INFO - SettingsFactory:248 - JPA-QL strict compliance: enabled
12:14:59,191 -  INFO - SettingsFactory:253 - Second-level cache: enabled
12:14:59,191 -  INFO - SettingsFactory:257 - Query cache: disabled
12:14:59,196 -  INFO - SettingsFactory:382 - Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
12:14:59,196 -  INFO - RegionFactoryCacheProviderBridge:61 - Cache provider: org.hibernate.cache.NoCacheProvider
12:14:59,197 -  INFO - SettingsFactory:267 - Optimize cache for minimal puts: disabled
12:14:59,197 -  INFO - SettingsFactory:276 - Structured second-level cache entries: disabled
12:14:59,202 -  INFO - SettingsFactory:296 - Echoing all SQL to stdout
12:14:59,216 -  INFO - SettingsFactory:305 - Statistics: disabled
12:14:59,216 -  INFO - SettingsFactory:309 - Deleted entity synthetic identifier rollback: disabled
12:14:59,217 -  INFO - SettingsFactory:324 - Default entity-mode: pojo
12:14:59,217 -  INFO - SettingsFactory:328 - Named query checking : enabled
12:14:59,258 -  INFO - SessionFactoryImpl:193 - building session factory
12:14:59,885 -  INFO - SessionFactoryObjectFactory:105 - Not binding factory to JNDI, no JNDI name configured
```


----------



## byte (10. Aug 2009)

[c]org.postgresql.util.PSQLException extends java.sql.SQLException[/c]


----------



## -MacNuke- (10. Aug 2009)

byte hat gesagt.:


> Und wie kriegt der TE dann die SQL Exception in der Konsole, wenn Hibernate die offenbar verschluckt? :autsch:



Hibernate loggt die Exception selbst. Siehe meinen Codeauszug


----------



## si031006 (23. Nov 2009)

Hat jetzt eigentlich schon einer eine Lösung für dieses Problem gefunden (hab nämlich das gleiche)?

Und noch was:
Weiss jemand wie ich die ganzen Ausgaben an die Console von Hibernate unterbinde?


Danke


----------



## -MacNuke- (24. Nov 2009)

si031006 hat gesagt.:


> Hat jetzt eigentlich schon einer eine Lösung für dieses Problem gefunden (hab nämlich das gleiche)?



Ich habe es jetzt halt so gelöst, dass ich beim Start erst mal mit DriverManager.getConnection prüfe, ob ich so eine Verbindung kriege. Ist zwar nicht besonders schön, aber da Hibernate die Exception frisst, kann man da wohl nichts anderes machen.



si031006 hat gesagt.:


> Und noch was:
> Weiss jemand wie ich die ganzen Ausgaben an die Console von Hibernate unterbinde?



Kommt drauf an, welchen slf4j "Provider" du nimmst. Bei log4j (in meinem Fall) kann man über die log4j.properties einstellen, was Hibernate alles loggen soll und wohin:


```
# Hibernate logging options
log4j.logger.org.hibernate=ERROR
#log4j.logger.org.hibernate.SQL=DEBUG

# Log JDBC bind parameter runtime arguments
log4j.logger.org.hibernate.type=ERROR
```


----------



## si031006 (25. Nov 2009)

Danke, das hilft mir schon weiter.

Noch was:
Ich verwende (leider auch nicht änderbar) eine MS-Access Datenbank. 
Setze ich jetzt ein SQL ab, also konkret folgendes:

SELECT Name FROM MSysObjects WHERE type = 1

sagt er mir, das die Tabelle nicht gefunden wird. Klar, weil ich auch nirgends ein passendes Mapping habe 
(mit vorher angelegter XML und Java Datei).

MEINE FRAGE NUN:
Kann ich in Hibernate auch diverse SQLs absetzen, ohne die passende Tabelle vorher mittels xml und class Datei angegeben zu haben. Sprich, ein stinknormales Recordset zu bekommen?
Habe hierfür die Methode createSQLQuery benutzt, aber vielleicht gibts ja auch andere Methoden für diesen Fall?

Danke!


----------

