NetBeans, GlassFish and Hibernate JPA - mysql

On work, im using Eclipse, Jboss and Hibernate JPA. For a smaller, private project I like to use Netbeans, GlassFish and Hibernate JPA.
Problem: I want hibernate to generate the tables automagically - but it won't do that for me.
What i did:
First, i installed - obvious is obvious - Netbeans, Glassfish and a local MySQL-DB.
I created a JDBC-Connection for Glassfish:
url: jdbc:mysql://localhost:3306/myDatabase?zeroDateTimeBehavior=convertToNull
name: myDatabaseJDBC
Driver: com.mysql.jdbc.Driver
The connection seems fine, "testing" it resolved to a successful connection.
Now i created the persistance.xml like this:
<?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="primary" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>myDatabaseJDBC</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
Then i added the required depoendencies to my Project (using maven) and the hibernate Plugin to Glassfish
What works: When ive created a table, in Netbeans i can Select New -> Other -> Persistance -> Entity Class from Database. The connection shows the tables, i select one, click okay, and i got the entity.
However i usually work the other way round and let hibernate generate my tables from the created entities... That whoever won't work. (It even looks like Hibernate is not even invoked, when building the project)
Did I miss any configuration step?
update: -------------
I wanted to test if hibernate is "active" in any way. So i created a simple entity, a controller and deployed the application with a single button.
public void doSth() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("primary");
EntityManager em = emf.createEntityManager();
CEntity c = new CEntity();
c.setName("Test");
em.persist(c);
}
first, i received an exception:
Caused by: org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:376)
Overhere: hibernate, mysql, glassfish v3, and JTA datasource i found the solution to add
// For GlassFish:
hibernate.transaction.manager_lookup_class=org.hibernate.transaction.SunONETransactionManagerLookup
to the persistance.xml. The exception is now gone, but i received another one: Unknown Entity: CEntity.
I figured out, that hibernate can NOT find my entities. (Yes, i used javax.persistance.Entity and not the one from the hibernate namespace). However "adding" the entity manually to the persistance.xml solves the issue and also the automatic table-creation is invoked.
However, now im looking for the correct configuration, so adding every Entity to persistance.xml is NOT required.
I set <exclude-unlisted-classes>false</exclude-unlisted-classes> but hibernate seems to ignore that...

The key was to add:
<property name="hibernate.archive.autodetection" value="class"/>
to persistence.xml's properties-collection. After all:
<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="primary">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>myDatabaseJDBC</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManagerLookup"/>
<property name="hibernate.archive.autodetection" value="class"/>
</properties>
</persistence-unit>
</persistence>

Related

Unable to access mysql from jpa after Catalina update

My jpa application was working fine (in fact, my 2 jpa applications) since I update my mac to Catalina (and restart it, of course).
Since then I got
org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator initiateService
WARN: HHH000342: Could not obtain connection to query metadata : null
Exception in thread "main" org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
...
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
But from mySQL Workbench I can access my databases with no problem.
I've tried to reinstall mysql, even using brew to do it. Nothing works.
I changed nothing on my persistence.xml file nor my code.
<?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="MyProject" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/myschema"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="MyPassword"/>
<property name="javax.persistence.schema-generation.database.action" value="update"/>
</properties>
</persistence-unit>
</persistence>
My mysql version is 8.0.19.
Thank you!
Next day update (28/4):
By now, I have:
1) Added this line to my persistence.xml:
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
As I got a new error...
Access denied for user 'root'#'localhost' (using password: YES)
2) Followed this instructions to set root password:
https://medium.com/#aungzanbaw/how-to-reset-root-user-password-in-mysql-8-0-a5c328d098a8
Now my new error is
Connection refused
Next next day update (29/4):
Today I stoped and started mysql from terminal:
sudo /usr/local/bin/mysql.server stop
sudo /usr/local/bin/mysql.server start
I then I got a new error
The server time zone value 'CEST' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support.
Let's continue my investigation!
Following this question: https://es.stackoverflow.com/questions/48935/configurar-zona-horaria-jdbc-driver-java/48946?newreg=494e1840d4404575a81dc4ec10200266
I modified persistence.xml:
So I got a
Table 'myschema.mytable' doesn't exist
error.
Finally I got it, not sure how... probably restarting from comand line.
Here my final persistence.xml:
<?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="MyProject" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="MyPassword"/>
<property name="javax.persistence.schema-generation.database.action" value="update"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect" />
</properties>
</persistence-unit>
</persistence>
Using MySQL8Dialect is necessary to be able to create the tables without that error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'type=MyISAM' at line 1

Mysql Driver class com.mysql.jdbc.Driver is not a valid javax.sql.DataSource implementation from wildfly

maybe my setup is quite special, but I do have issues when I define a JDBC Datasource for Java EE container in my web.xml file.
I configured my Datasource in my web.xml as follow:
<data-source>
<name>java:app/myapp/DS</name>
<class-name>com.mysql.jdbc.Driver</class-name>
<url>jdbc:mysql://localhost:3306/database?useSSL=false&allowPublicKeyRetrieval=true</url>
<user>foo</user>
<password>pass</password>
<transactional>true</transactional>
<isolation-level>TRANSACTION_READ_COMMITTED</isolation-level>
<initial-pool-size>2</initial-pool-size>
<max-pool-size>10</max-pool-size>
<min-pool-size>5</min-pool-size>
<max-statements>0</max-statements>
</data-source>
After I use datasource's name as my jta-data-source in my persistence file as follow:
<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="java-rs-with-hibernate" transaction-type="JTA">
<jta-data-source>java:app/myapp/DS</jta-data-source>
<class>com.patrickhub.ch.java_rs_with_hibernate.domain.Product</class>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="none"/>
<property name="javax.persistence.schema-generation.scripts.action" value="none"/>
</properties>
</persistence-unit>
</persistence>
And in my code I used the EntityManager to make request to the database.
But when I deploy it to wildfly 18.0.1, I get the following errors:
at org.jboss.as.connector#18.0.1.Final//org.jboss.as.connector.subsystems.datasources.AbstractDataSourceService.start(AbstractDataSourceService.java:174)
at org.jboss.msc#1.4.11.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1739)
at org.jboss.msc#1.4.11.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1701)
at org.jboss.msc#1.4.11.Final//org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1559)
at org.jboss.threads#2.3.3.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads#2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
at org.jboss.threads#2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads#2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1363)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.jboss.jca.deployers.common.DeployException: WFLYJCA0030: unable to deploy
at org.jboss.as.connector#18.0.1.Final//org.jboss.as.connector.subsystems.datasources.AbstractDataSourceService$AS7DataSourceDeployer.deploy(AbstractDataSourceService.java:376)
at org.jboss.as.connector#18.0.1.Final//org.jboss.as.connector.subsystems.datasources.AbstractDataSourceService.start(AbstractDataSourceService.java:160)
... 8 more
Caused by: org.jboss.as.controller.OperationFailedException: WFLYJCA0117: com.mysql.jdbc.Driver is not a valid javax.sql.DataSource implementation [ "WFLYJCA0117: com.mysql.jdbc.Driver is not a valid javax.sql.DataSource implementation" ]
... 10 more
I think that if I replace com.mysql.jdbc.Driver with com.mysql.jc.jdbc.Driver, it will deploy successfully but I still have the same problem and the same message error.
I don't know if I miss something on how to define a mysql JDBC datasource in web.xml file. but I think it is correct.
Please can someone help me.

Wildfly 10 persistence MySQL table not found

I have a REST service which access a MySQL database. I'm using Wildfly 10 and MySQL 5.7.12. I am trying to get the EntityManager as an injection and I get the following error when executing the find method for my Entity mapping the table content.
org.h2.jdbc.JdbcSQLException: Table "MYTABLE" not found; SQL statement:
In the RESTService class I have
#PersistenceContext(unitName="myUnit")
protected EntityManager entityManager;
and my persistence.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
version="2.1">
<persistence-unit name="myUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mytable" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="pass" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.archive.autodetection" value="class, hbm"/>
</properties>
</persistence-unit>
</persistence>
The issue is that if instead of using injection I retrieve the entity manager using the manual way everything works smothly.
EntityManagerFactory emFactory;
emFactory = Persistence.createEntityManagerFactory("myUnit");
EntityManager em = emFactory.createEntityManager();
Could you give me some hints on how to use the PersistenceContext? the code is somehow cleaner and I prefer to use it.
It looks like you 're getting the default datasource injected in your persistence Unit so I guess this depends on how the EntityManager is 'built'. One way to fix this is to create a datasource in WidFly and use it (through) its JNDI name in your persistence unit.
Feel free to report a bug http://issues.jboss.org/
You are setting up a RESOURCE_LOCAL persistence unit. You should configure it as such:
<persistence-unit transaction-type="RESOURCE_LOCAL">
In order to use a resource local persistence unit you cannot inject EntityManager, only EntityManagerFactory. You'll end up with a lot less plumbing if you switch to JTA datasource and let the server manage it.
If you absolutely don't want to edit standalone.xml, in WF8 anyway, you can drop yourdatasource-ds.xml file into your WEB-INF folder, or into the deployments directory alongside your .war file. There was talk of removing this from WF though so I don't know if it works in 10.x.

Connecting to remote database server

I'm developing an application in a container managed environment (Java EE). Therefore, I shouldn't have to worry about handling and closing transactions. I simply inject the EntityManager:
#PersistenceContext(unitName = "WebApplication")
private EntityManager em;
And my corresponding 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="WebApplication" transaction-type="JTA">
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"></property>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://link-to-my-database.us-east-1.rds.amazonaws.com:3306/TestDB"></property>
<property name="javax.persistence.jdbc.user" value="admin"/>
<property name="javax.persistence.jdbc.password" value="password"/>
<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>
However, this does not work. According to the JPA 2.0 specification, javax.persistence.jdbc.driver is "attended for use in Java SE environments." (Section 8.2.1.9; page 317). And even the jta-datasource and non-jta-datasource only "name the data source in the local environment" (Section 8.2.1.5; page 313).
Then how can I connect to a remote database server? Obviously, I can explicitly create an EntityManager but then I would be responsible for handling the transactions, then what's the point of being in a container managed environment? If it's possible to connect to a remote database server using JPA and a container managed environment, can you provide an example on how to do so?

Do I need DataSource in JPA Hibernate project?

I am preparing some application with usage of JPA 2.0, Hibernate as provider, MySQL 5 as database, which will be deployed on JBoss AS 7.0.2.I have already configured some basics in persistence.xml and I came into some kind of trouble. I have noticed that some people also defines some specific DataSource on JBoss Management Console level.
My question is. Do I really need to worry about some DataSource or anything like that in Hibernate application?I thought it is important in old JDBC approach.In some books, where examples are shown, there is no such configuration in persistence.xml or hibernate.cfg.xml
Do I have to place mysql connector into JBOSS_HOME/standalone/deployments directory to use MySQL in my application?Here is content of my persistence.xml file:
<?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="SomeApp">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/somedb" />
<property name="hibernate.connection.username" value="" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
</properties>
</persistence-unit>
</persistence>
Well, you can either access the database by:
providing the url/driver/password/etc. information in the persistence.xml using your jpa-provider properties (in your case hibernate.connection.*) or the JPA 2.0 standardised javax.persistence.jdbc.* ones - this basically looks like the example you've posted,
creating a Data Source in the ApplicationServer and just referring to it in the persistence.xml (through it's JNDI name you provide during creation) which might look similar to this (without the XML schema definition for the sake of brevity) :
<persistence>
<persistence-unit name="SomeApp">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/myDB</jta-data-source>
</persistence-unit>
</persistence>
What you're actually doing right now (with these properties) is using the JDBC.
I would definitely go with the creation of the Data Source in the ApplicationServer rather than providing it in the properties in persistence.xml. It allows you to dynamically change the end-database, it's type, credentials, manage connection pools, etc. without even touching your descriptor.
It's also safer, as the credentials are not written in the plain file left on your server.
As a side note, please remember that the javax.persistence.jdbc.* properties are a JPA provider must requirement for the Java SE environment, but it's optional for Java EE.
Hope that helps!
Do I have to place mysql connector into
JBOSS_HOME/standalone/deployments directory to use MySQL in my
application?
Yes you need to put Mysql J/connector for use it as JDBC Driver. Your application server (JBOss, Weblogic, Glassfish, etc) doesn't provide it because depend of the RDBMS that you are using (in this case Mysql) and the version of it.
In the case of JBoss 7 the JDBC driver can be installed into the container in one of two ways: either as a deployment or as a core module. For the pros/cons of both modes an detailed explanatio you can check the following documentation: http://community.jboss.org/wiki/DataSourceConfigurationInAS7