Search code examples
javamysqljpaormeclipselink

When I run program JPA does not create table in MySQL


Here is my entity named Class:

package az.bank.entities;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table (name = "cards")
public class Card implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String cardHolder;
    private String cardNumber;
    private String cardPassword;
    private String expiryYear;
    private String expiryMonth;
    private String cardType;
    private double cardBalance;   
}

And here is my persistance.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="BankServicePU" transaction-type="JTA">
        <jta-data-source>jdbc/BankService</jta-data-source>
        <class>az.bank.entities.Card</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/cards" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="javax.persistence.schema-generation.database.action" value="create"/>
        </properties>
    </persistence-unit>
</persistence>

I have created connection pool named jdbc/BankService and mySQL scheme named cards. But when I deploy and run program it does not create table in that scheme. Please help what have I done wrong here.


Solution

  • I suppose that in your case you don't initialize the EntityManagerFactory which means that your eclipselink does not receive a command to create a tables and even connect to the DB.

    In your case you can try to use ServletContextListener which have to be regestered withing your web.xml file.

    Quick example:

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
             version="3.0">
        <listener>
            <listener-class>
                com.mberazouski.stackoverflow.AppServletContextListener
            </listener-class>
        </listener>
    </web-app>
    

    Starting Servlet 3.0 you can just use @WebListener annotation instead registration in web.xml.

    AppServletContextListener.java

    package com.mberazouski.stackoverflow;
    
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    public class AppServletContextListener implements ServletContextListener {
        private static EntityManagerFactory emf;
    
        public void contextInitialized(ServletContextEvent event) {
            emf = Persistence.createEntityManagerFactory("default");
            createEntityManager();
        }
    
        public void contextDestroyed(ServletContextEvent event) {
            emf.close();
        }
    
        public static EntityManager createEntityManager() {
            if (emf == null) {
                throw new IllegalStateException("Context is not initialized yet.");
            }
    
            return emf.createEntityManager();
        }
    }
    

    So your persistence.xml is absolutely valid. Adapted to my domain model file looks like:

    RESOURCE_LOCAL

    You can configure your connection through the RESOURCE_LOCAL.

    <?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="default" transaction-type="RESOURCE_LOCAL">
            <class>com.mberazouski.stackoverflow.domain.Cards</class>
            <properties>
                <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
                <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/rsreu"/>
                <property name="javax.persistence.jdbc.user" value="root"/>
                <property name="javax.persistence.jdbc.password" value="root"/>
                <property name="javax.persistence.schema-generation.database.action" value="create"/>
            </properties>
        </persistence-unit>
    </persistence>
    

    jta-data-source

    In this case all configurations will be taken from Resource block from your tomcat:

    <?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="default" transaction-type="JTA">
            <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
            <jta-data-source>java:comp/env/jdbc/EclispeLinkDB</jta-data-source>
            <class>com.mberazouski.stackoverflow.domain.Cards</class>
            <properties>
                <property name="javax.persistence.schema-generation.database.action" value="create"/>
            </properties>
        </persistence-unit>
    </persistence>
    

    Output of the tomcat start: enter image description here

    But I also suggest you to look into direction of spring. Using it initializer approach you can initialize EntityManagerFactory directly from configuration file.

    applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
        <bean id="emf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean ">
            <property name="persistenceUnitName" value="default"/>
        </bean>
    </beans>
    

    Hope this will help.