Connecting to remote database server - mysql

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?

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

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.

Play 2.3 JPA Hibernate MySQL Pooling/Connection Error

I'm developing a Play 2.3 Application with JPA/Hibernate and use a Heroku/ClearDB.com MySQL Database for this but after the application connects successfully to the DB I get following error:
[error] c.j.b.h.AbstractConnectionHook - Failed to acquire connection to jdbc:mysql://eu-cdbr-west-01.cleardb.com:3306/heroku_b7ea7b2d2972532 Sleeping for 1000ms and trying again. Attempts left: 10. Exception: null.Message:User 'badd25925bdd5f' has exceeded the 'max_user_connections' resource (current value: 10)
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: User 'badd25925bdd5f' has exceeded the 'max_user_connections' resource (current value: 10)
I tried almost everything I saw on other posts but nothing helped... I think it has to do with pooling...?
persistence.xml
<?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="defaultPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://eu-cdbr-west-01.cleardb.com:3306/heroku_b7ea7b2d2972532?reconnect=true"/>
<property name="javax.persistence.jdbc.user" value="badd25925bdd5f"/>
<property name="javax.persistence.jdbc.password" value="XXX"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.c3p0.min_size" value="2"/>
<property name="hibernate.c3p0.max_size" value="9"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="3000"/>
</properties>
</persistence-unit>
</persistence>
application.conf (relevant part)
db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://eu-cdbr-west-01.cleardb.com:3306/heroku_b7ea7b2d2972532"
db.default.user="badd25925bdd5f"
db.default.password="XXX"
jpa.default=defaultPersistenceUnit
Thanks a lot for your help!
I don't know about using Hibernate, but with Ebean the connection pool by default is managed by BoneCP. Try to configure it in your application.conf:
# Max connections = partitionCount * maxConnPerPartition
db.default.partitionCount=2
db.default.maxConnectionsPerPartition=5
or in your persistence.xml:
<property name="bonecp.partitionCount" value="2" />
<property name="bonecp.maxConnectionsPerPartition" value="5" />
The error says that you are using more connections then your plan .So you can
Either upgrade you db plans see https://addons.heroku.com/cleardb#ignite
or
You can try scaling down your aplication see https://devcenter.heroku.com/articles/scaling
Solution to this problem (for Play 2.3) was to add the play-hikaricp library to the application.

Netbeans/Glassfish - not connecting with jdbc using sun-resources.xml

I'm trying to get a Netbeans/Glassfish Enterprise application to run locally on my pc (it is currently working in production). I've gotten as far as the login display, but when I try to log in, the app throws the following exception:
SEVERE: "com.sun.enterprise.security.auth.login.common.LoginException: Login failed: javax.security.auth.login.LoginException: Failed file login for myloginname".
And the login servlet forwards to a login error page.
The web.xml in the "-web" project looks like this:
<resource-ref>
<res-ref-name>jdbc/my_name_MySQL</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
There's also a persistence.xml set up as follows:
<?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="modCompJar-PU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/my_name_MySQL</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManagerLookup"/>
<property name="hibernate.query.factory_class" value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory"/>
<property name="hibernate.search.default.indexBase" value="/opt/index/webInput"/>
</properties>
</persistence-unit>
</persistence>
Finally, there's a sun-resources.xml, which looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Resource Definitions //EN" "http://www.sun.com/software/appserver/dtds/sun-resources_1_3.dtd">
<resources>
<jdbc-resource enabled="true" jndi-name="jdbc/my_name_MySQL" object-type="user" pool-name="MyPool">
<description/>
</jdbc-resource>
<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.Driver" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="MyPool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
<property name="URL" value="jdbc:mysql://localhost:33306/mydatabsename?relaxAutoCommit="true""/>
<property name="User" value="root"/>
</jdbc-connection-pool>
</resources>
Note I've set up a tunnel via Putty to use a remote database, thus the "33306" for the mysql port instead of 3306.
I also changed Netbeans to point to the remote server's database, using the tunneled port. That works because the clicking on the "Database" node under the "Services" shows the same databases as exist on the remote server.
I know the login is correct because when I log in to the application running on the server, I get in, and they're both accessing the same database.
I also noticed there are some jdbc connection pools set up in "domain.xml" which refer to non-existent databases and ip addresses. The only valid database is the one shown above, in "sun-resources.xml".
How can I get this app to connect to the right database?

NetBeans, GlassFish and Hibernate JPA

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>