I am trying to understand all the properties for schemas generation of JPA 2.1 using EclipseLink implementation and a Mysql database, but I had several bugs easy to explain but difficult to debug
Here is my persistence.xml document
<?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="fairHandlerPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>nrz.fairHandler.jpa.Unit</class>
<class>nrz.fairHandler.jpa.Weight</class>
<class>nrz.fairHandler.jpa.Pruduct</class>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/fairhandlerdb?zeroDateTimeBehavior=convertToNull"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.schema-generation.create-database-schemas" value="true"/>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties>
</persistence-unit>
</persistence>
Everything work fine in execution if the schema 'fairhandlerdb' is already created, whether the 'fairhandlerdb' tables exists or not, however, if the schema don't exist it will return an exception at runtime:
Exception in thread "main" javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'fairhandlerdb'
which for me is a contradiction since this property job
<property name="javax.persistence.schema-generation.create-database-schemas" value="true"/>
is to create schema if this one does not exist.
After that, I tried to resolve the problem in another way by executing a creating schemas script, by adding these properties:
<property name="javax.persistence.schema-generation.script.create-source" value="script-then-metadata"/>
<property name="javax.persistence.schema-generation.script.drop-source" value="metadata"/>
<property name="javax.persistence.schema-generation.script.create-script-source" value="META-INF/createSchema.sql"/>
where createSchema.sql contain only one query:
CREATE SCHEMA `fairhandlerdb` ;
But it does not work neither when the database schema does not already exist at execution time.
My question is, why the two methods used above, didn't work for generating the database schema?
Thank you for your help
Related
I have created two entities in my JAVA code one is Account entity, another is AccountLog entity. These two entities mapped to the corresponding table in same schema named testdb. We use hibernate and JPA to handle the insert/update and table generation.
Since the performance issue, I would like to separate the AccountLog into other schema named testdb_log. So that the AccountLog table will be generated in schema testdb_log and the next insert/update event will be stored in the schema testdb_log.
What is the best solution to handle the above cases? Add #table annotation with schema name? or others?
How to generate the entity to other schema?
For this entity, how to save/update this entity information to other schema?
I will probably use different persistence units in the persistence xml, something like this:
<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="oneschema" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<properties>
<property name="driverClass" value="${db.driver}" />
<property name="jdbcUrl" value="${datasource.baseurl}/SCHEMAONE" />
<property name="user" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
</properties>
</persistence-unit>
<persistence-unit name="anotherchema" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.company.AccountLog</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="driverClass" value="${db.driver}" />
<property name="jdbcUrl" value="${datasource.baseurl}/SCHEMANOTHER" />
<property name="user" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
</properties>
</persistence-unit>
</persistence>
In the second persistence unit you declare explicitly what classes belong to it, so the entity manager will know how to deal with them.
Schema, connections, connection pools are usually transparent to the java code so you shouldn't change anything in java.
I'm currently learning Hibernate and JPA and I just stumbled upon the following issue:
I have an entity class called User, and this class is annotated with the #Entity (JPA) annotation. My persistence.xml file does NOT have a mapping for it, yet I can use it on my EntityManager without issues.
I just created another entity, called Comment (some packages below), this one is also annotated with #Entity and is also NOT on my persistence.xml file. This one however, throws a org.hibernate.MappingException: Unknown entity exception when used on the EntityManager.
My persistence.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="net.notfab.hibernatetest" transaction-type="RESOURCE_LOCAL">
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<!-- JPA Properties -->
<property name="javax.persistence.provider" value="org.hibernate.jpa.HibernatePersistenceProvider"/>
<property name="javax.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:mariadb://IP:PORT...."/>
<property name="javax.persistence.jdbc.user" value=""/>
<property name="javax.persistence.jdbc.password" value=""/>
<!-- Hibernate Properties -->
<property name="hibernate.connection.provider_class"
value="org.hibernate.hikaricp.internal.HikariCPConnectionProvider"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MariaDBDialect"/>
<property name="hibernate.connection.CharSet" value="utf8mb4_bin"/>
<property name="hibernate.connection.characterEncoding" value="utf8mb4_bin"/>
<property name="hibernate.connection.useUnicode" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.archive.autodetection" value="class, hbm" />
<!-- Hikari Properties -->
<property name="hibernate.hikari.minimumIdle" value="5"/>
<property name="hibernate.hikari.maximumPoolSize" value="10"/>
<property name="hibernate.hikari.idleTimeout" value="15000"/>
<property name="hibernate.hikari.leakDetectionThreshold" value="30000"/> <!-- 30 Seconds -->
<property name="hibernate.hikari.poolName" value="TestPool"/>
</properties>
</persistence-unit>
</persistence>
What may be causing this weird behavior?
Is there a way for me to continue using the annotated classes without having to declare them on the XML file? (It's 2018 already - Annotations are way better!).
Note: This question is similar but their end goal ended up being mapping on the XML, which I'm trying to avoid by all means. I'm also looking for an explanation to the above-mentioned behavior.
Edit: As requested by the comments, here is the full stacktrace https://hastebin.com/haguniheca.cs (as well as here https://hasteb.in/ipuzojoc.cs in case hastebin goes down again).
In this scenario, I'm not using Spring.
Edit 2: Here is my entity.
Edit 3: This is a gradle project, running off of a standalone (shaded) jar file on Java SE, currently using the following list of dependencies for persistence (among others):
compile group: 'org.hibernate', name: 'hibernate-hikaricp', version: '5.3.3.Final'
compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.2.6'
Edit 4: As per Eugen's comment I did some testing and the cause of the issue seems to be IntelliJ. By running the shaded jar file on it's own from the command line, the issue is fixed. (Maybe the classpath is different when running off of the application debug?). The question then becomes "how can I fix IntelliJ's run configuration for my app?".
I am creating a server in Glassfish and I want to have a JPA persistence layer to a remote MySQL database.
When I attempt to use the persistence layer, I get this exception: javax.persistence.PersistenceException: No Persistence provider for EntityManager named em1
Based on other StackOverflow posts, it seems this is an indication the persistence.xml is invalid. My persistence.xml is shown. Can someone point me in the right direction to figuring out how to get this to work?
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name ="em1">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>data.entry.Movie</class>
<properties>
<property name="eclipselink.target-database"
value="MySQL4"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="mysql3.cs.myschool.edu/mydb"/>
<property name="javax.persistence.jdbc.user" value="mydb" />
<property name="javax.persistence.jdbc.password" value="mypass" />
</properties>
</persistence-unit>
</persistence>
I am using eclipse IDE.I also try following two .but failed..when i manually create table in my mysql database then my complete program run fine... I want create table automatic with respect to entity class.
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.hbm2ddl.auto">update</property>
here my persistence 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="JpaTest2" transaction-type="RESOURCE_LOCAL">
<class>com.jpa.Employee</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/hibernate"/>
<property name="javax.persistence.jdbc.user" value="umar"/>
<property name="javax.persistence.jdbc.password" value="umar"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
Dont use Hibernate specific options. JPA 2.1 provides
javax.persistence.schema-generation.database.action
that can be set to "create", "drop", "drop-and-create", "none".
That way you keep your code JPA implementation independent
Check your entity. Did you miss #Table annotation? The exception clearly says that the table is missing 'hibernate.employee':
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'hibernate.employee' doesn't exist at ...
If you defined a naming strategy that prepends all tables with hibernate., then make sure that the tables are created in MySql.
I was able to get JPA working with eclipse Luna and installing eclipseLink (and created a User Lib with the 3 jars).
However, I have now moved to Rational Application Developer (RAD) and attempting to use the JPA that is delivered with WAS Liberty. I initially used RAD JPA facet to configure JPA and then edited persistence.xml.
I am getting this error:
Caused by: javax.persistence.PersistenceException: No persistence providers available for "test2" after trying the following discovered implementations: NONE
I assume (always dangerous) the NONE is a configuration error and I cannot do anything until that is resolved...
I have copied the wlp\dev\api\spec\com.ibm.ws.javaee.persistence.2.0_1.0.1.jar into WEB-INF/lib and included that in my java build path.
As you can see below, I was guessing my provider was not correct, and tried several values...
<?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="test2" transaction-type="RESOURCE_LOCAL">
<!-- provider>org.eclipse.persistence.jpa.PersistenceProvider</provider-->
<!-- provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider-->
<provider>com.ibm.websphere.persistence.PersistenceProviderImpl</provider>
<non-jta-data-source>java:comp/env/New Generic JDBC</non-jta-data-source>
<class>com.ibm.analytics.jpa.Dimtask</class>
<properties>
<property name="openjpa.jdbc.Schema" value="RM"/>
<property name="javax.persistence.jdbc.url" value="jdbc:netezza://netezza-1.site.ibm.com:5480/DATABASENAME"/>
<property name="javax.persistence.jdbc.user" value="jspoon"/>
<property name="javax.persistence.jdbc.password" value="xxxxxxx"/>
<property name="javax.persistence.jdbc.driver" value="org.netezza.Driver"/>
</properties>
</persistence-unit>
</persistence>
What else can I do to get past the NONE?
Here is the updated version of persistence.xml, I just commented out the provider.
<?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="test2" transaction-type="RESOURCE_LOCAL">
<!-- provider>org.eclipse.persistence.jpa.PersistenceProvider</provider-->
<!-- provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider-->
<!-- provider>com.ibm.websphere.persistence.PersistenceProviderImpl</provider-->
<non-jta-data-source>java:comp/env/New Generic JDBC</non-jta-data-source>
<class>com.ibm.analytics.jpa.Dimtask</class>
<properties>
<property name="openjpa.jdbc.Schema" value="RM"/>
<property name="javax.persistence.jdbc.url" value="jdbc:netezza://netezza-1.boulder.ibm.com:5480/BACC_TST_ISHANGO_DW"/>
<property name="javax.persistence.jdbc.user" value="jspoon"/>
<property name="javax.persistence.jdbc.password" value="C0ke4y0u"/>
<property name="javax.persistence.jdbc.driver" value="org.netezza.Driver"/>
</properties>
</persistence-unit>
</persistence>
I created my Entity class using JPA Tooling, and using a simple junit test to call a named query. The first step is to create the EMF and it is a static in my class (so none of the test is actually running, it is failing at instantiation creating the static variable):
static EntityManagerFactory emf = Persistence.createEntityManagerFactory( "test2" );
This is the exact same code as used before with eclipse and eclipseLink.