2010-01-05 7 views
1

Si je mets la mauvaise URL de connexion dans mon fichier hibernate.cfg.xml, je veux être capable de le détecter et de terminer gracieusement, mais je n'arrive pas à comprendre comment; il se bloque juste indéfiniment buildSessionFactory() pendant la procédure d'initialisation de mise en veille prolongée:Catch invalide hibernate erreur d'URL de connexion

SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory(); 

Il est dans un bloc d'essai, et je suis en train d'attraper une exception générique, mais buildSessionFactory() jette jamais un, il se bloque juste. Ceci est l'élément URL dans mon hibernate.cfg.xml:

<property name="hibernate.connection.url">jdbc:mysql://123.123.123.123/mydb</property> 

Mon système: Ubuntu 9.10 avec Tomcat 5.5, Java 1.6, Hibernate 3 et MySQL 5.

Quand je veille prolongée INITIALISER, juste se bloque pendant 22 secondes, puis se met à cracher des avertissements sur les discussions et l'impasse (en commençant par ce sujet):

15:16:25,758 WARN ThreadPoolAsynchronousRunner.class: com[email protected]a010ba -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
15:16:25,761 WARN ThreadPoolAsynchronousRunner.class: com[email protected]a010ba -- APPARENT DEADLOCK!!! Complete Status: 
Managed Threads: 3 
Active Threads: 3 
Active Tasks: 
    [email protected]3 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0) 
    [email protected]e (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2) 
    [email protected] (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1) 
Pending Tasks: 
    [email protected]4 
    [email protected]2 
Pool thread stack traces: 
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main] 
    java.net.PlainSocketImpl.socketConnect(Native Method) 
    java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) 
    java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) 
    java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) 
    java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) 
    java.net.Socket.connect(Socket.java:525) 
    java.net.Socket.connect(Socket.java:475) 
    java.net.Socket.<init>(Socket.java:372) 
    java.net.Socket.<init>(Socket.java:215) 
    com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:253) 
    com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:284) 
    com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2194) 
    com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:723) 
    com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46) 
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 
    java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
    com.mysql.jdbc.Util.handleNewInstance(Util.java:406) 
    com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302) 
    com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282) 
    com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:135) 
    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182) 
    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171) 
    com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137) 
    com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014) 
    com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32) 
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810) 
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 

EDIT: voici mes propriétés c3p0 de mon hibernate.cfg.xml

<property name="hibernate.c3p0.acquire_increment">1</property> 
<property name="hibernate.c3p0.idle_test_period">100</property> 
<property name="hibernate.c3p0.max_size">100</property> 
<property name="hibernate.c3p0.max_statements">100</property> 
<property name="hibernate.c3p0.min_size">5</property> 
<property name="hibernate.c3p0.timeout">100</property> 
+0

Le délai que vous voyez est probablement causé par les propriétés acquireRetryDelay et acquireRetryAttempts de c3p0 qui réessayent la connexion après une courte pause (la valeur par défaut est 1 seconde). Dans l'ensemble, il semble stupide (à moins qu'il y ait quelque chose à propos de votre installation, je ne comprends pas) de mettre beaucoup d'efforts pour faire votre application gérer les erreurs de configuration simples. – BryanD

+0

Merci pour votre réponse. S'il vous plaît voir mon commentaire sur la réponse de Pascal. – jackocnr

Répondre

0

Comme BryanD mentionné dans un commentaire, buildSessionFactory() n'est pas vraiment suspendu, le temps est très probablement passé dans c3p0 qui essaie de se reconnecter. Citant le c3p0 documentation:

Quand une tentative DataSource de c3p0 et ne parvient pas à acquérir une connexion, il va réessayer jusqu'à acquireRetryAttempts fois, avec un retard de acquireRetryDelay entre chaque tentative. Si toutes les tentatives échouent, tous les clients qui attendent des connexions à partir de DataSource verront une exception indiquant qu'une connexion n'a pas pu être acquise. Notez que les clients ne voient aucune exception jusqu'à ce qu'un cycle complet de tentatives échoue, ce qui peut être un certain temps après la tentative de connexion initiale. Si acquireRetryAttempts est défini sur 0, c3p0 tentera d'acquérir de nouvelles connexions indéfiniment et les appels au getConnection() peuvent bloquer indéfiniment l'attente d'une acquisition réussie.

Si vous ne le configurer, la valeur par défaut du acquireRetryAttempts est 30 donc il peut en effet prendre un certain temps pour buildSessionFactory() pour revenir. Mais, à moins que vous n'utilisiez une valeur inférieure ou égale à zéro, auquel cas c3p0 continuera à essayer d'extraire une connexion indéfiniment, il le fera.

Peut-être pourriez-vous utiliser une valeur inférieure. Ou peut-être pourriez-vous simplement utiliser la bonne URL et arrêter de passer du temps sur une situation exceptionnelle (une erreur de configuration).

+0

Merci pour l'info. J'ai essayé de définir c3p0.acquireRetryAttempts = 1 (et confirmé qu'il était défini avec la sortie de débogage) mais il s'est comporté exactement de la même manière. Je pose seulement des questions à propos de tout cela parce que je teste mon application sur quelques serveurs différents, et j'ai perdu beaucoup de temps à déterminer ce qui n'allait pas lorsque l'application était suspendue indéfiniment alors que j'avais simplement oublié de mettre à jour l'URL de connexion. Je pensais qu'il pourrait y avoir une solution simple pour attraper cette erreur pour sauver moi-même et d'autres de perdre du temps à corriger les erreurs de configuration dans le futur ... – jackocnr