web-dev-qa-db-fra.com

référence de source de données JNDI Tomcat dans persistence.xml

dans server.xml, j'ai défini la ressource globale (j'utilise Tomcat 6 ):

<GlobalNamingResources>
   <Resource name="jdbc/myds" auth="Container"
             type="javax.sql.DataSource"
             maxActive="10" maxIdle="3" maxWait="10000"
             username="sa"  password=""
             driverClassName="org.h2.Driver"
             url="jdbc:h2:~/.myds/data/db"
   />
</GlobalNamingResources>

Je vois dans catalina.out que cela est lié, donc je suppose que ça va.

Dans mon application Web, j'ai le lien vers la source de données, je ne suis pas sûr que ce soit OK:

<Context>    
 <ResourceLink global='jdbc/myds' name='jdbc/myds' type="javax.sql.Datasource"/>    
</Context>

et dans l'application il y a persistence.xml:

<persistence xmlns="http://Java.Sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://Java.Sun.com/xml/ns/persistence http://Java.Sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
  <persistence-unit name="oam" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <non-jta-data-source>jdbc/myds</non-jta-data-source>
    <!-- class definitions here, nothing else -->

    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
    </properties>
  </persistence-unit>
</persistence>

Cela devrait aller, mais il est fort probable que cette définition de ResourceLink ou celle-ci soit erronée car je reçois:

javax.naming.NameNotFoundException: Le nom jdbc n'est pas lié dans ce contexte.

Quel est le problème et pourquoi cela ne fonctionne pas? 

UPDATE:

J'ai essayé d'obtenir la source de données directement: 

public class WebAppListener implements ServletContextListener
{
    // ServletContextListener interface - start
    public void contextInitialized(ServletContextEvent sce)
    {
        try
        {
            Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("Java:comp/env");
            DataSource ds = (DataSource)
            envCtx.lookup("jdbc/myds");
        }
        catch (NamingException ex)
        {
            System.out.println("!!!! Got NamingException:");
            ex.printStackTrace(System.out);
        }
    }

    public void contextDestroyed(ServletContextEvent sce) { }

}

mon web.xml:

  <listener>
    <display-name>Listener</display-name>
    <listener-class>WebAppListener</listener-class>
  </listener>

Toujours la même erreur même si je vois la source de données dans la console JMX lorsque je me connecte au Tomcat (Catalina - Datasource - javax.sql.Datasource = "jdbc/myds": ObjectName = Catalina: type = DataSource, class = javax.sql.DataSource, name = "jdbc/myds".)

12
Rostislav Matl

Le <non-jta-data-source> dans persistence.xml devrait être

Java:comp/env/jdbc/myds

selon la réponse dans http://forums.Oracle.com/forums/thread.jspa?messageID=1899677

Et aussi est votre pilote de base de données dans $CATALINA_HOME/lib

10
JoseK

(J'utilise la bibliothèque Apache OpenJPA dans Tomcat7 et ne correspond donc peut-être pas à Hibernate)

Je n'ai jamais utilisé de jdbc global pour mes applications Web OpenJPA, mais je l'ai essayé. Cela a fonctionné et ceci est ma configuration. Voir le dossier où persistence.xml est enregistré, probablement un problème openjpa, mais sans cela rien ne fonctionne.

myapp/WEB-INF/classes/META-INF/persistence.xml
Ceci utilise openjpa provider, une liste de classes peut ne pas être nécessaire en veille prolongée.

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="1.0" xmlns="http://Java.Sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<persistence-unit name="main" transaction-type="RESOURCE_LOCAL">
    <provider>org.Apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <non-jta-data-source>Java:comp/env/jdbc/mydb</non-jta-data-source>

    <class>com.myapp.db.User</class>
    <class>com.myapp.db.Server</class>

    <properties>
        <property name="openjpa.DynamicEnhancementAgent" value="false" />
        <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported" /> 
        <property name="openjpa.Log" value="commons" />
        <property name="openjpa.ConnectionFactoryProperties" value="PrintParameters=true" />
    </properties>
</persistence-unit>

</persistence>

Tomcat/conf/server.xml
Ajouter une ressource globale jdbc.

  ..cut...
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.Apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.Apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/Tomcat-users.xml" readonly="true"  />

    <Resource name="jdbc/mydb" auth="Container" type="javax.sql.DataSource"
        maxActive="100" maxIdle="20" maxWait="10000"
        username="myuser" password="mypwd"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/mydb?useUnicode=true&amp;characterEncoding=utf8"
        validationQuery="SELECT 1" removeAbandoned="true" removeAbandonedTimeout="300"
    />
  </GlobalNamingResources>
  ..cut...

Tomcat/conf/Catalina/localhost/myapp.xml
ceci est ma boîte de développement et j'utilise donc docBase pour établir un lien direct avec le dossier des projets. Vous devriez trouver l'insertion de ce paquet dans war (META-INF/context.xml) lors du déploiement dans la zone de production.

<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="/projects/myapp/web" reloadable="true" crossContext="true" >

  <Realm className="org.Apache.catalina.realm.DataSourceRealm"
    dataSourceName="jdbc/mydb" localDataSource="false" digest="SHA"
    userTable="user"            userNameCol="username" userCredCol="password"
    userRoleTable="user_role_v" roleNameCol="role" 
  />

  <ResourceLink name="jdbc/mydb" global="jdbc/mydb" type="javax.sql.DataSource" />
</Context>

myapp/WEB-INF/web.xml
Ajoutez resource-ref à la fin du fichier.

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://Java.Sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://Java.Sun.com/xml/ns/javaee http://Java.Sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0" >

  <description>Webapp</description>
  <display-name>Webapp</display-name>
  ..cut...

  <resource-ref>
    <description>mydb</description>
    <res-ref-name>jdbc/mydb</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

</web-app>

Étant donné que j'utilise OpenJPA + Tomcat7 (pas le conteneur j2ee complet), cela peut sembler excessif, mais c'est comme cela que ça fonctionne. Les résultats sont bons et il est très facile de développer des applications Web compatibles avec la base de données. Inutile de recourir à des classes manuelles de code SQL et de DAO oldskool.

1
Whome

Avez-vous rendu cette ressource disponible pour l'application en la déclarant dans votre web.xml?

<resource-ref>
  <description>DB Connection</description>
  <res-ref-name>jdbc/myds</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>
0
Pascal Thivent