How to use JNDI with the tc server and postgresql

2019-08-23 07:03发布

问题:

I want to use JPA/JNDI, as my experience with Netbeans and Glassfish has been that I could configure database settings at the server and so I'd be able to publish to different servers without changing anything in the code or configuration.

I don't really get what's wrong and paste my configuration here in the hope that you can help me with some advice.

I successfully tried to get a database connection with this persistence unit:

<persistence-unit name="primefaces-showcase"
    transaction-type="RESOURCE_LOCAL">
    <class>org.primefaces.showcase.domain.Car</class>
    <properties>
        <property name="javax.persistence.schema-generation.database.action"
            value="drop-and-create" />
        <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/database" />
        <property name="javax.persistence.jdbc.user" value="postgres" />
        <property name="javax.persistence.jdbc.password" value="pass" />
        <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
        <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
    </properties>
</persistence-unit>

I used it like this

EntityManagerFactory emf =
Persistence.createEntityManagerFactory("primefaces-showcase");
EntityManager em = emf.createEntityManager();

But when I want to use JNDI like this

    @PersistenceContext(unitName = "primefaces-jta")
    private EntityManager em;

I get this console output that tells me it can't create initial connections of pool:

Sep 29, 2014 2:09:39 PM org.apache.catalina.startup.SetContextPropertiesRule begin
WARNUNG: [SetContextPropertiesRule]{Context} Setting property 'source' to 'org.eclipse.jst.jee.server:primefaces-showcase' did not find a matching property.
Sep 29, 2014 2:09:42 PM org.apache.tomcat.jdbc.pool.ConnectionPool init
SCHWERWIEGEND: Unable to create initial connections of pool.
java.sql.SQLException
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:254)
    at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:701)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:635)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:486)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:144)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
    at org.apache.tomcat.jdbc.pool.DataSourceFactory.createDataSource(DataSourceFactory.java:554)
    at org.apache.tomcat.jdbc.pool.DataSourceFactory.getObjectInstance(DataSourceFactory.java:242)
    at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:141)
    at javax.naming.spi.NamingManager.getObjectInstance(Unknown Source)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:842)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:830)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:167)
    at org.apache.catalina.core.NamingContextListener.addResource(NamingContextListener.java:1093)
    at org.apache.catalina.core.NamingContextListener.createNamingContext(NamingContextListener.java:672)
    at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:270)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5355)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:670)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1839)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:246)
    ... 32 more

/primefaces-showcase/src/main/java/org/primefaces/showcase/service/CarService.java

@ManagedBean(name = "carService")
@ApplicationScoped
public class CarService {

    @PersistenceContext(unitName = "primefaces-jta")
    private EntityManager em;

    public List<Car> createCars(int size) {

        List<Car> list = new ArrayList<Car>();
        for (int i = 0; i < size; i++) {
            em.getTransaction().begin();
            Car car = new Car(getRandomId(), getRandomBrand(), getRandomYear(),
                    getRandomColor(), getRandomPrice(), getRandomSoldState());
            list.add(car);
            em.persist(car);
            em.getTransaction().commit();
        }
        return list;
    }

/primefaces-showcase/src/main/java/META-INF/persistence.xml

<persistence-unit name="primefaces-jta"
    transaction-type="JTA">
    <jta-data-source>jdbc/postgres</jta-data-source>
    <properties>
        <property name="javax.persistence.schema-generation.database.action"
            value="drop-and-create" />
        <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
    </properties>
</persistence-unit>

/primefaces-showcase/src/main/java/META-INF/context.xml

<Context>
    <Resource name="jdbc/postgres" auth="Container" type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
        driverClassName="org.postgresql.Driver" url="jdbc:postgresql://127.0.0.1:5432/database"
        username="postgres" password="pass" maxActive="20" maxIdle="10"
        maxWait="-1" />
<!--    <ResourceLink global="jdbc/postgres" name="jdbc/postgres" -->
<!--        type="javax.sql.DataSource" /> -->
</Context>

/primefaces-showcase/src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">

    <!-- SPRING ROOT WEB APPLICATION CONTEXT -->

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>


    <!-- SPRING SECURITY -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <servlet-name>Spring MVC Servlet</servlet-name>
    </filter-mapping>

    <!-- JSF 2 IMPLEMENTATION -->

    <!-- Use JSF view templates saved as *.xhtml, for use with Facelets -->
    <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.xhtml</param-value>
    </context-param>

    <!-- Enables special Facelets debug output during development -->
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>

    <!-- Causes Facelets to refresh templates during development -->
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>1</param-value>
    </context-param>

    <!-- Just here so the JSF implementation can initialize, *not* used at runtime -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Just here so the JSF implementation can initialize -->
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>

    <!-- SPRING MVC -->

    <servlet>
        <servlet-name>Spring MVC Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Spring MVC Servlet</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Spring MVC Servlet</servlet-name>
    </filter-mapping>

    <!-- Spring Security Facelets tag library declaration -->
    <context-param>
        <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
        <param-value>/WEB-INF/springsecurity.taglib.xml</param-value>
    </context-param>

    <!-- DEFAULT PAGE -->

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <resource-ref>
        <description>postgreSQL Datasource example</description>
        <res-ref-name>jdbc/postgres</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

</web-app>

UPDATE 2014-10-09:

Problem solved by adding the driver to pom.xml

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.3-1100-jdbc41</version>
    </dependency>

回答1:

Make sure you have the postgres driver library in the classpath.