Search code examples
javapostgresqljpaopenjpaapache-tomee

simple creation of DB with OpenJPA and postgresql


I think to have some problem with my version of TomEE but once it works so good.... when I try to create the database something goes wrong... this is the stack:

objc[1068]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java and /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
424  unisocial-database  INFO   [main] openjpa.Runtime - OpenJPA dynamically loaded the class enhancer. Any classes that were not enhanced at build time will be enhanced when they are loaded by the JVM.
522  unisocial-database  INFO   [main] openjpa.Runtime - OpenJPA dynamically loaded a validation provider.
537  unisocial-database  INFO   [main] openjpa.Runtime - Starting OpenJPA 2.4.0-nonfinal-1598334
Exception in thread "main" <openjpa-2.4.0-nonfinal-1598334-r422266:1599166    
fatal user error> org.apache.openjpa.persistence.ArgumentException: 
The persistence provider is attempting to use properties 
in the persistence.xml file to resolve the data source. 
A Java Database Connectivity (JDBC) driver or data source class
name must be specified in the openjpa.ConnectionDriverName or 
javax.persistence.jdbc.driver property. The following properties
are available in the configuration:  
"org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl@80992065".

    at org.apache.openjpa.jdbc.schema.DataSourceFactory.newDataSource(DataSourceFactory.java:72)
    at org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.createConnectionFactory(JDBCConfigurationImpl.java:849)
    at org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.getDBDictionaryInstance(JDBCConfigurationImpl.java:602)
    at org.apache.openjpa.jdbc.meta.MappingRepository.endConfiguration(MappingRepository.java:1518)
    at org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:535)
    at org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:460)
    at org.apache.openjpa.lib.conf.PluginValue.instantiate(PluginValue.java:121)
    at org.apache.openjpa.conf.MetaDataRepositoryValue.instantiate(MetaDataRepositoryValue.java:68)
    at org.apache.openjpa.lib.conf.ObjectValue.instantiate(ObjectValue.java:83)
    at org.apache.openjpa.conf.OpenJPAConfigurationImpl.newMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:967)
    at org.apache.openjpa.conf.OpenJPAConfigurationImpl.getMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:958)
    at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:642)
    at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:202)
    at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:155)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:226)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:153)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:59)
    at eu.algoritmi.unisocial.model.MainP.main(MainP.java:14)

this is my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>

<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="unisocial-database"
        transaction-type="JTA">

        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <jta-data-source>unisocial database</jta-data-source>
        <class>eu.algoritmi.unisocial.model.UtenteNonGiuridico</class>
        <class>eu.algoritmi.unisocial.model.Corso</class>
        <class>eu.algoritmi.unisocial.model.Facolta</class>
        <class>eu.algoritmi.unisocial.model.Universita</class>
        <class>eu.algoritmi.unisocial.model.Studente</class>
        <class>eu.algoritmi.unisocial.model.UtenteNonGiuridico</class>

        <properties>
            <property name="openjpa.jdbc.SynchronizeMappings"
                value="buildSchema(SchemaAction=add,ForeignKeys=true)" />
            <property name="openjpa.Log"
                value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE" />
            <property name="openjpa.jdbc.MappingDefaults"
                value="ForeignKeyDeleteAction=restrict,JoinForeignKeyDeleteAction=restrict" />
            <property name="openjpa.RuntimeUnenhancedClasses" value="supported" />

            <property name="javax.persistence.schema-generation.database.action"
                value="drop-and-create" />
            <property
                name="javax.persistence.schema-generation.create-database-schemas"
                value="true" />
        </properties>

    </persistence-unit>
</persistence>

this is the resouces.xml

<tomee>
    <Resource id="unisocial database" type="DataSource">
        JdbcDriver          org.postgresql.Driver
        JdbcUrl             jdbc:postgresql://localhost/unisocial
        UserName            unisocial
        Password            unisocial
        JtaManaged          true
        DefaultAutoCommit   false
    </Resource>
</tomee>

this is the main class used to demonstrate the effect.

package eu.algoritmi.unisocial.model;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class MainP {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("unisocial-database");
        EntityManager em = emf.createEntityManager();

        Universita u=new Universita("romaTre", null);

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        em.persist(u);
        tx.commit();

        em.close();
        emf.close();
    }       
}

Solution

  • The issue relates to this message in the stacktrace:

    A Java Database Connectivity (JDBC) driver or data source class name must be specified in the openjpa.ConnectionDriverName or javax.persistence.jdbc.driver property.

    Inspecting your provided persistence.xmlwe can see, that you forgot to provide one of both properties. One of both is mandatory, so your TomEE environment can determine which JDBC driver to use when connecting to your PostgreSQL backend. A persistence.xmlconfigured as follows should fix your problem:

    <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="unisocial-database"
            transaction-type="JTA">
            <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
            <jta-data-source>unisocial database</jta-data-source>
            <class>eu.algoritmi.unisocial.model.UtenteNonGiuridico</class>
            <class>eu.algoritmi.unisocial.model.Corso</class>
            <class>eu.algoritmi.unisocial.model.Facolta</class>
            <class>eu.algoritmi.unisocial.model.Universita</class>
            <class>eu.algoritmi.unisocial.model.Studente</class>
            <class>eu.algoritmi.unisocial.model.UtenteNonGiuridico</class>
    
            <properties>
    
                <!-- Generic JPA configuration attributes -->
                <property name="javax.persistence.jdbc.driver"
                    value="org.postgresql.Driver" />
                <property name="javax.persistence.schema-generation.database.action"
                    value="drop-and-create" />
                <property name="javax.persistence.schema-generation.create-database-schemas"
                    value="true" />
    
                <!-- OpenJPA specific configuration attributes -->
                <property name="openjpa.jdbc.SynchronizeMappings"
                    value="buildSchema(SchemaAction=add,ForeignKeys=true)" />
                <property name="openjpa.Log"
                    value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE" />
                <property name="openjpa.jdbc.MappingDefaults"
                    value="ForeignKeyDeleteAction=restrict,JoinForeignKeyDeleteAction=restrict" />
                <property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
    
            </properties>
    
        </persistence-unit>
    </persistence>
    

    Remember to copy the latest JAR file of the PostgreSQL driver to the lib directory of your TomEE installation. This way, the driver will be found across different web applications that are deployed in your container.

    Hope it helps.