JPA Eclipse "Generating Tables From Entities" hangs forever - java

On a Windows 8 64bit machine, in Eclipse Luna, I use JPA (EclipseLink 2.5.x) and Apache Derby as JDBC connection.
My persistence.xml so far:
<?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="ReportWriter" transaction-type="RESOURCE_LOCAL">
<class>com.example.Clazz</class>
<class>com.example.CommentBank</class>
<class>com.example.CommentCategory</class>
<class>com.example.CourseWork</class>
<class>com.example.GradeModel</class>
<class>com.example.Pupil</class>
<class>com.example.PupilCoursework</class>
<class>com.example.Report</class>
<class>com.example.Year</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:derby:D:\rwdb.db"/>
<property name="javax.persistence.jdbc.user" value="rwdbuser"/>
<property name="javax.persistence.jdbc.password" value="rwdbpassword"/>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="eclipselink.jdbc.exclusive-connection.is-lazy" value="true"/>
</properties>
</persistence-unit>
</persistence>
Using the wizard, I created a new database connection in Eclipse which works pretty well.
When I want to do JPA Tools => Generate Tables From Entities, eclipse starts creating tables... and continues forever. There's no exception, no other message, it just blocks on this operation.
I cannot even cancel it. If I try to do so, it just adds "Cancel requested" to the item and keeps going. Closing eclipse isn't possible either, as it's awaiting the finish of its current operations.
.metadata\.log doesn't contain any new information about this.
Oh and I chose "sql-script" as output, just in case.
Any ideas?

The classes that should be generated already have to be listed in persistence.xml.
Once I did this, it worked.

The reason it takes forever is that the primary process is single-threaded and probably developed by someone using legacy style coding. Even if you have 8 CPUs, the process can only use a single thread and a limited amount of memory.

Related

correct way to include a database connection to POSTGRES in payara micro war file

I managed to deploy and use a JPA connection using the below files.
This is currently working, but it's not ideal.
The connection should be using the postgres pool driver, and a JNDI data source rather than a data source in web.xml.
What is the best practice way of deploying a database connection in a JEE container.
Here is my current setup, using a global connection that is not using the pooled driver.
persistence.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.1"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="pcc" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:global/pccData</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.deploy-on-startup" value="true"/>
<property name="eclipselink.logging.level" value="INFO"/>
<property name="eclipselink.logging.level.sql" value="CONFIG"/>
<property name="eclipselink.jdbc.fetch-size" value="1000"/>
<property name="eclipselink.jdbc.cache-statements" value="true"/>
<property name="eclipselink.persistence-context.flush-mode" value="commit"/>
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
</properties>
</persistence-unit>
</persistence>
web.xml
I am sure PGSimpleDataSource is not the recommended approach
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>PCC Web Application</display-name>
<data-source>
<name>java:global/pccData</name>
<class-name>org.postgresql.ds.PGSimpleDataSource</class-name>
<server-name>localhost</server-name>
<port-number>5432</port-number>
<database-name>pcc</database-name>
<user>postgres</user>
<password>postgres</password>
<property>
<name>fish.payara.slow-query-threshold-in-seconds</name>
<value>5</value>
</property>
</data-source>
</web-app>
To answer your question:
What is the best practice way of deploying a database connection in a JEE container?
This is pretty much it.
It doesn't need to be any more complex than the set up you currently have. I assume you have already seen the official Payara-Examples repository but, if not, there is a JPA example there which is configured exactly as you have in your question:
https://github.com/payara/Payara-Examples/blob/master/Payara-Micro/jpa-datasource-example/ReadMe.md
As a general point about configuring Payara Micro, you can think of it as a Payara Server in a different package, so if you're still unsure about something and want to do things in the same way as in the more traditional server then you can do.
There are --postbootcommandfile and --postdeploycommandfile options which will allow you to run asadmin commands against Payara Micro and configure it just like Payara Server.
For your connection pool example, if you really wanted to define it in the server (really, defining it in the web.xml as you already have done is more portable and would be my preferred option), then you could start a normal Payara Server, click the button to enable asadmin command recording in the admin console, and then make the changes using the GUI. The necessary commands will then by dumped to a file for you to apply to Payara Micro later.
Payara Micro also dumps out a temporary directory (controllable with --rootDir, by default has the same value as java.io.tmpdir) so you can always see how a configuration change has affected it by inspecting the domain.xml in that directory structure. This gives you some form of manual verification.

Re-create database at runtime using EclipseLink

Is there a way to recreate the database dynamically at Run-Time in EclipseLink?
Right now I have it that if the database does not exist, it creates the database at compilation time :
<?xml version="1.0" encoding="UTF-8" ?>
<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" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="DefaultUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
<property name="eclipselink.logging.level" value="INFO" />
<property name="eclipselink.logging.level.sql" value="INFO" />
<property name="javax.persistence.schema-generation.database.action"
value="create" />
</properties>
</persistence-unit>
</persistence>
However, I want to be able to Drop, and Recreate the database while the application is running. I.E when a user passes in some special flag, I want to call something that will drop the current database, and regenerate it.
I found that you can do that in Hibernate using the SchemaExport class
You can add <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> into persistence.xml.
It will delete all table and create it again. Be careful, all your earlier data will be lost.
absolutely. Properties can be added dynamically at runtime, so you can add the "eclipselink.ddl-generation" with value "drop-and-create-tables" when you create the EntityManagerFactory for the first time to have it drop and create the database. Of course, this isn't much use to a running app where you want to change things on the fly.
To get around this, EclipseLInk has a few tricks that allow dynamic changes and reloading of the persistence unit. Try
Map properties = new HashMap();
properties.put("eclipselink.ddl-generation", "drop-and-create-tables");
properties.put("eclipselink.ddl-generation.output-mode", "database");
//this causes DDL generation to occur on refreshMetadata rather than wait until an em is obtained
properties.put("eclipselink.deploy-on-startup", "true");
JpaHelper.getEntityManagerFactory(em).refreshMetadata(properties);
The org.eclipse.persistence.jpa.JPAHelper class is just used to unwrap the Factory to get a JpaEntityManagerFactory instance to make the non-JPA refreshMetadata call. Any number of properties or settings can be changed, and any new EntityManagers obtained after the refresh call will reflect those changes.

Why is there no transaction in my thread? JPA JTS/JTA Glassfish 4

I'm writing a small EJB3 application deployed on glassfish 4 and using the derbyDB that comes with glassfish.
To make testing easy I have declared one of my EJBs as #Webservice so I can trigger a method with the testers provided by glassfish. So far so good.
The callstack is like this:
DailyReportingJob( #Stateless and #WebService, EntryPoint for my test)
--> VerfahrensArchivService (#Stateless and #Transactional(value = TxType.REQUIRES_NEW) )
my persistence.xml is like this:
<?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="zvagent">
<jta-data-source>jdbc/zvagentdb</jta-data-source>
<class>de.kevinfleischer.zvagent.verfahren.Verfahren</class>
<properties>
<property name="eclipselink.logging.level" value="FINE"/>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="eclipselink.deploy-on-startup" value="true"/>
</properties>
</persistence-unit>
</persistence>
I've configured a connection pool in glassfish of ressource type javax.sql.DataSource and a jdbc ressource with the name jdbc/zvagentdb that points to this pool.
When I trigger the webservice I see my app working. But when I try to call the VerfahrensArchivService - which should store data to the DB - the following warning shows up. In the webinterface of the webservice tester I see further an InvocationTargetException, telling me the call to "doPost" failed.
WARNING: javax.ejb.EJBException: java.lang.IllegalStateException: Transaction is not active in the current thread.
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2016)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1979)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy455.storeAndUpdateVerfahren(Unknown Source)
at de.kevinfleischer.zvagent.archiv.__EJB31_Generated__VerfahrensArchivService__Intf____Bean__.storeAndUpdateVerfahren(Unknown Source)
at de.kevinfleischer.zvagent.job.DailyReportingJob.executeJob(DailyReportingJob.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
The DB is empty afterwards. No Data was stored.
(I have JUnit tests, that work completely local without appserver, that show, that the code would store data. So its a transaction problem, not a problem in the business code.)
I finally found that the configuration was no problem. The packaging was rubbish and the errors I got only follow up errors.

My persistence Unit is pinning to the fjords, when used for a remote connection

While i does manage to connect to my database through the "Services" netbeans tab, my application persistent unit seems to not be working... It just seems to go in an endless "Wait some more, maybe we'll connect you later..." cycle.
Question 1: Why isn't it working?
Question 2 (if no reasons for 1): How can i produce a small work-around?
Here is my persistent unit statement:
entityManager = java.beans.Beans.isDesignTime() ? null : javax.persistence.Persistence.createEntityManagerFactory(resourceMap.getString("entityManager.persistenceUnit")).createEntityManager();
The resourceMap.getString("entityManager.persistenceUnit")just allow me to access the property field which define my persistence unit.
Here is my persistence.xml:
<?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" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="analyses_2PU" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>analysesmanager.Produits</class>
<class>analysesmanager.Lots</class>
<class>analysesmanager.SpecProduits</class>
<class>analysesmanager.Parametres</class>
<class>analysesmanager.Clients</class>
<class>analysesmanager.Resultats</class>
<class>analysesmanager.Analyses</class>
<properties>
<property name="toplink.jdbc.user" value="XXXXX"/>
<property name="toplink.jdbc.password" value="XXX"/>
<property name="toplink.jdbc.url" value="jdbc:mysql://172.17.22.15:3306/soliance_analyses"/>
<property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
</properties>
</persistence-unit>
</persistence>
While this doesn't work with my distant mysql server, it works on my local server using a local copy of the database...
The only difference is between those 2 lines...
<property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/soliance_analyses"/>
<property name="toplink.jdbc.url" value="jdbc:mysql://172.17.22.15:3306/soliance_analyses"/>
By the way, running my local version, directly on the remote server does work... It seems to be an issue with either the network (which would not be solvable), either the persistence.xml used for remote connection.
Small work-around:
I have put my project local version on the remote server, and i now run it locally on the remote server, through a .bat .
Here is the ROFLMAO_it_works.bat
net use X: \\remote_server_ip\project_jar_path
X:
java -jar X:\project.jar
It works. Not the way i wanted at the very beginning, but it works.

javax.persistence.PersistenceException: No Persistence provider for EntityManager named customerManager

I am new to JPA & Hibernate. After reading some online materials I now understand what Hibernate is and how it can be used with JPA.
Now, I am trying to run this JPA & Hibernate tutorial. I've done everything they mention in this tutorial.
I don't have Oracle DB, only MySQL. So I made some changes to persistence.xml using my understanding of JPA & Hibernate (I don't know if it's correct or not... Seems to me it is.)
Here is my 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_1_0.xsd" version="1.0">
<persistence-unit name="customerManager" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Customer</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="1234"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/general"/>
<property name="hibernate.max_fetch_depth" value="3"/>
</properties>
</persistence-unit>
</persistence>
But I don't seem to get the output they describe. It's giving me:
Customer id before creation:null
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named customerManager
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
at CustomerDAO.create(CustomerDAO.java:8)
at CustomerDAO.main(CustomerDAO.java:22)
Any suggestions will be appreciated.
Update:
I have made the changes that are asked to done. But, still getting the asme error lines!!!
They didnt mentioned anything about orm.xml in that tutorial. may it be a problem causer!!!
Just for completeness. There is another situation causing this error:
missing META-INF/services/javax.persistence.spi.PersistenceProvider
file.
For Hibernate, it's located in hibernate-entitymanager-XXX.jar, so, if hibernate-entitymanager-XXX.jar is not in your classpath, you will got this error too.
This error message is so misleading, and it costs me hours to get it correct.
See JPA 2.0 using Hibernate as provider - Exception: No Persistence provider for EntityManager.
Your persistence.xml is not valid and the EntityManagerFactory can't get created. It should be:
<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_1_0.xsd" version="1.0">
<persistence-unit name="customerManager" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Customer</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="1234"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/general"/>
<property name="hibernate.max_fetch_depth" value="3"/>
</properties>
</persistence-unit>
</persistence>
(Note how the <property> elements are closed, they shouldn't be nested)
Update: I went through the tutorial and you will also have to change the Id generation strategy when using MySQL (as MySQL doesn't support sequences). I suggest using the AUTO strategy (defaults to IDENTITY with MySQL). To do so, remove the SequenceGenerator annotation and change the code like this:
#Entity
#Table(name="TAB_CUSTOMER")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="CUSTOMER_ID", precision=0)
private Long customerId = null;
...
}
This should help.
PS: you should also provide a log4j.properties as suggested.
I had the same problem today. My persistence.xml was in the wrong location. I had to put it in the following path:
project/src/main/resources/META-INF/persistence.xml
I was facing the same issue. I realised that I was using the Wrong provider class in persistence.xml
For Hibernate it should be
<provider>org.hibernate.ejb.HibernatePersistence</provider>
And for EclipseLink it should be
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
If you use Hibernate 5.2.10.Final, you should change
<provider>org.hibernate.ejb.HibernatePersistence</provider>
to
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
in your persistence.xml
According to Hibernate 5.2.2: No Persistence provider for EntityManager
If you are using Maven you may have both src/{main,test}/resources/META-INF/persistence.xml. This is a common setup: test your JPA code with h2 or Derby and deploy it with PostgreSQL or some other full DBMS. If you're using this pattern, do make sure the two files have different unit names, else some versions of the Persistence class will try to load BOTH (because of course your test-time CLASSPATH includes both classes and test-classes); this will cause conflicting definitions of the persistence unit, resulting in the dreaded annoying message that we all hate so much!
Worse: this may "work" with some older versions of e.g., Hibernate, but fail with current versions. Worth getting it right anyway...
A bit too late but I got the same issue and fixed it switching schemalocation into schemaLocation in the persistence.xml file (line 1).
I have seen this error , for me the issue was there was a space in the absolute path of the persistance.xml , removal of the same helped me.
I was also facing the same issue when I was trying to get JPA entity manager configured in Tomcat 8. First I has an issue with the SystemException class not being found and hence the entityManagerFactory was not being created. I removed the hibernate entity manager dependency and then my entityManagerFactory was not able to lookup for the persistence provider. After going thru a lot of research and time got to know that hibernate entity manager is must to lookup for some configuration. Then put back the entity manager jar and then added JTA Api as a dependency and it worked fine.
my experience tells me that missing persistence.xml,will generate the same exception too.
i caught the same error msg today when i tried to run a jar package packed by ant.
when i used jar tvf to check the content of the jar file, i realized that "ant" forgot to pack the persistnece.xml for me.
after I manually repacked the jar file ,the error msg disappered.
so i believe maybe you should try simplely putting META-INF under src directory and placing your persistence.xml there.

Categories

Resources