# Tomcat Classloader findet bei JPA-Persistierung die Persistence Unit nicht.



## pkm (15. Sep 2019)

Ich verstehe nicht, wieso ich eine einfache Entity-Klasse (mit dem Namen Entity) nicht vermittels JPA persistieren kann. Der Apache-Log sagt:





> 15-Sep-2019 09:48:24.223 SEVERE [http-nio-8080-exec-20] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [DB] in context with path [/mave] threw exception
> 
> [ObjectDB 2.8.1] javax.persistence.PersistenceException
> 
> ...




Nun sieht die Sache bei mir so aus, dass ich eine PersistEntity-Klasse habe, in der ich eine persist-Methode aufrufe, der ein String übergeben ist. Jedoch scheitert es schon bei der Erschaffung der EntityManagerFactory:




```
/*

* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.

*/

package com.mavenproject.mave;

import javax.persistence.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PersistEntity {

private static final String PERSISTENCE_UNIT_NAME = "entities";
private static EntityManagerFactory factory;
private static final Logger LOGGER = Logger.getLogger(PersistEntity.class.getName());

void persist(String data) {

LOGGER.log(Level.SEVERE, "Create entity manager.");

factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

// EntityManager em = factory.createEntityManager();

LOGGER.log(Level.SEVERE, "Entity manager created.");

. . .

         }

}
```


Dabei habe ich eine persistence.xml, mit welcher das gehen müsste:



```
<persistence>
<persistence-unit name="entities">
<class>com.mavenproject.mave.Entity</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/userdata;create=true"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="eclipselink.logging.level" value="SEVERE"/>
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
</properties>
</persistence-unit>
</persistence>
```


Die Struktur meines Webprojekts habe ich mal als Anhang angefügt.


----------



## mihe7 (15. Sep 2019)

pkm hat gesagt.:


> Dabei habe ich eine persistence.xml,


Du hast sogar zwei, das könnte zum Problem werden... (unter webapp/META-INF und unter resources/META-INF).

EDIT: verwende mal nur die in resources/META-INF.


----------



## pkm (15. Sep 2019)

Danke, klappt!


----------



## pkm (16. Sep 2019)

Leider ist da erneut etwas, das ich nicht verstehe. Zwar kann ich nun wie gesagt eine EntityManagerFactory erzeugen, aber schon bei dem Entity Manager tritt ein neues Problem auf, das ich nicht verstehe. Meine persistence.xml sieht wie folgt aus:


```
<persistence version="2.0" 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">   
        
    <persistence-unit name="entity" transaction-type="RESOURCE_LOCAL">           
        <class>com.mavenproject.mave.Entity</class> 
      
    <properties> 
    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> 
    <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/userdata"/>
    <property name="javax.persistence.jdbc.user" value="root"/> 
    <property name="javax.persistence.jdbc.password" value="root"/> 
    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
    <property name="eclipselink.logging.level" value="SEVERE"/> 
    <property name="eclipselink.ddl-generation" value="create-or-extend-tables"/> 
    </properties> 
      
     </persistence-unit>
            
    </persistence>
```

Ich habe auf meinem Datenbankserver eine Datenbank namens userdata angelegt. Wenn ich nun die Entity persistieren will, kommt der Fehler: "Failed to create a new file 'jdbc:mysql://localhost:3306/userdata", diese Exception wird bei dem Methodenaufruf "factory.createEntityManager();" ausgelöst:


```
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mavenproject.mave;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class PersistEntity {

    private static final String PERSISTENCE_UNIT_NAME = "entity";
    private static EntityManagerFactory factory;

    private static final Logger LOGGER = Logger.getLogger(PersistEntity.class.getName());

    void persist(String data) {

        LoggerSetup.getInstance().doSetup(LOGGER);

        try {

            factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

        } catch (Exception e) {

            LOGGER.log(Level.SEVERE, "Encountered PersistException. - " + e.getMessage());

        }

                    LOGGER.log(Level.SEVERE, "Entity manager factory created.");
        
        EntityManager em = null;

        try {

            em = factory.createEntityManager();

        } catch (Exception e) {

            LOGGER.log(Level.SEVERE, "Encountered PersistException. - " + e.getMessage());

        }

        if (em != null) {

            LOGGER.log(Level.SEVERE, "Entity manager created.");
            
            em.getTransaction().begin();

            Entity s1 = new Entity();
                s1.setText(data);

            em.persist(s1);   
                
            em.getTransaction().commit();
            factory.close();
            em.close();

            LOGGER.log(Level.SEVERE, "Transaction done.");

        }
    }

}
```

Ich habe keine Ahnung, woran das liegen könnte.


----------



## Flown (16. Sep 2019)

Und der ganze StackTrace sieht wie aus?


----------



## mihe7 (17. Sep 2019)

pkm hat gesagt.:


> Ich habe keine Ahnung, woran das liegen könnte.


Wie @Flown schon schreibt: lass Dir mal den gesamten StackTrace ausgeben (z. B. im Catch ein `e.printStackTrace();` einfügen)


----------



## pkm (17. Sep 2019)

Der Stacktrace ist dieser:


```
Caused by: com.objectdb.o.UserException: Failed to create a new file 'jdbc:mysql://localhost:3306/userdata'
    at com.objectdb.o.MSG.a(MSG.java:77)
    at com.objectdb.o.LFL.m(LFL.java:870)
    at com.objectdb.o.LFL.x(LFL.java:810)
    at com.objectdb.o.DFL.<init>(DFL.java:241)
    at com.objectdb.o.DMG.<init>(DMG.java:27)
    at com.objectdb.o.MST.<init>(MST.java:127)
    at com.objectdb.o.MST.ap(MST.java:109)
    at com.objectdb.o.MSF.Yw(MSF.java:190)
    at com.objectdb.o.OMF.r(OMF.java:783)
    at com.objectdb.jpa.EMF.r(EMF.java:130)
    at com.objectdb.o.OMF.w(OMF.java:694)
    at com.objectdb.jpa.EMF.createEntityManager(EMF.java:149)
    ... 27 more
Caused by: java.io.FileNotFoundException: jdbc:mysql:\localhost:3306\userdata (Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch)
    at java.base/java.io.RandomAccessFile.open0(Native Method)
    at java.base/java.io.RandomAccessFile.open(RandomAccessFile.java:347)
    at java.base/java.io.RandomAccessFile.<init>(RandomAccessFile.java:261)
    at java.base/java.io.RandomAccessFile.<init>(RandomAccessFile.java:216)
    at com.objectdb.o.LFL.m(LFL.java:857)
```


----------



## mihe7 (17. Sep 2019)

?!? Evtl. wird der mysql-Treiber nicht gefunden und standardmäßig dann auf irgendwas anderes zurückgegriffen...


----------



## kneitzel (17. Sep 2019)

Öhm, Du willst doch ObjectDB nutzen. Wieso hast Du dann MySQL? Irgendwie widerspricht sich das doch gerade.

Du kannst JPA mit mysql nutzen, aber dann halt kein ObjectDB. Oder Du hast JPA mit ObjectDB.

Aber für eine Datenbank solltest Du Dich entscheiden.


----------



## mihe7 (17. Sep 2019)

kneitzel hat gesagt.:


> Öhm, Du willst doch ObjectDB nutzen. Wieso hast Du dann MySQL? Irgendwie widerspricht sich das doch gerade.


Hm.. dem Connection String zu urteilen, will er MySQL aber irgendwo kommt die ObjectDB daher.


----------



## kneitzel (17. Sep 2019)

Kann es daran liegen, dass er keinen Provider angegeben hat? Also sowas wie
<provider>org.hibernate.ejb.HibernatePersistence</provider>
Wenn kein Provider angegeben wurde, nimmt er meines Wissens nach den ersten, den er findet. Und falls er auch objectdb als Abhängigkeit in maven oder gradle oder so hat, dann zieht er da evtl. den falschen Provider (z.B. com.objectdb.jpa.Provider)?

Aber ohne Details zu wissen, ist das schwer zu urteilen.

Edith meint: der Provider würde in der persistence.xml mit angegeben.


----------



## pkm (17. Sep 2019)

Vielen Dank für Eure Beiträge. Jetzt klappt auch dieses. Es scheit ein TimezoneProblem gewesen zu sein:



> String url = "jdbc:mysql://"+hostname+":"+port+"/"+dbname+"?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";


----------

