JPA does not honours caching while creating entity manager factory dynamically - java

I am using hibernate 4.2 and working on J2ee6 with tomee 1.7.4 . I need to write multi-tenant code, which can connect to various databases on demand. I tried doing this by creating multiple persistence units in persistence.xml, but during server startup tomee tries to validate connection to all persistence units(all of them might not be available during testing).
I tried to find some setting that tells tomee to skip validation of the connections at startup, but couldn't find one. So instead of creating entitymanager from persistence unit, I started using the function
javax.persistence.Persistence.createEntityManagerFactory(String persistenceUnitName, Map properties)
and my persistence xml did not had any properties. This helped me solve this problem, but my caching stopped working when i moved to this model, it was working previously.
Can any one suggest some way in which i can ask tomee to skip validating persistence units at startup, or i can enable caching in the other way that i found.
My previous persistence.xml looked like
<?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="localDB" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/xxxxxx?autoReconnect=true" />
<property name="hibernate.connection.username" value="xxxxx" />
<property name="hibernate.connection.password" value="xxxxx" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.c3p0.acquire_increment" value="1"/>
<property name="hibernate.c3p0.max_size" value="40"/>
<!-- it must be set to LESS than the wait_timout setting for the mysql server (this setting defaults to 28800 secs (8 hours)) -->
<property name="hibernate.c3p0.idle_test_period" value="28680" />
<property name="hibernate.c3p0.preferredTestQuery" value="select 1;" />
<property name="hibernate.c3p0.timeout" value="60000"/>
<property name="hibernate.connection.zeroDateTimeBehavior" value="convertToNull"/>
<property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces " value="true"/>
<property name="debugUnreturnedConnectionStackTraces " value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.region.factory_class" value="com.mc.hibernate.memcached.MemcachedRegionFactory" />
<property name="hibernate.memcached.operationTimeout" value = "40000"/>
<property name="hibernate.memcached.connectionFactory" value = "KetamaConnectionFactory"/>
<property name="hibernate.memcached.hashAlgorithm" value = "HashAlgorithm.FNV1_64_HASH"/>
<property name="hibernate.memcached.servers" value = "xxxxx:xxxx"/>
<property name="hibernate.cache.region_prefix" value=""/>
</properties>
</persistence-unit>
<persistence-unit name="production" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://xxxxx:3306/thewalkindb?autoReconnect=true" />
<property name="hibernate.connection.username" value="xxxx" />
<property name="hibernate.connection.password" value="xxxxx" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.c3p0.acquire_increment" value="1"/>
<property name="hibernate.c3p0.max_size" value="15"/>
<!-- it must be set to LESS than the wait_timout setting for the mysql server (this setting defaults to 28800 secs (8 hours)) -->
<property name="hibernate.c3p0.idle_test_period" value="28680" />
<property name="hibernate.c3p0.preferredTestQuery" value="select 1;" />
<property name="hibernate.c3p0.timeout" value="60000"/>
<property name="hibernate.connection.zeroDateTimeBehavior" value="convertToNull"/>
<property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces " value="true"/>
<property name="debugUnreturnedConnectionStackTraces " value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.region.factory_class" value="com.mc.hibernate.memcached.MemcachedRegionFactory" />
<property name="hibernate.memcached.operationTimeout" value = "40000"/>
<property name="hibernate.memcached.connectionFactory" value = "KetamaConnectionFactory"/>
<property name="hibernate.memcached.hashAlgorithm" value = "HashAlgorithm.FNV1_64_HASH"/>
<property name="hibernate.memcached.servers" value = "xxxxxxxx"/>
<property name="hibernate.cache.region_prefix" value=""/>
</properties>
</persistence-unit>
this works with caching , but it doesnot gives me flexibility to skip validation at tomee startup
My new persistence xml which does not honours caching, but allows me the flexibility is as follows
<?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="localDB" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties></properties>
</persistence-unit>
<persistence-unit name="production" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
</properties>
</persistence-unit>
I am populating all the properties in a map and calling the function
javax.persistence.Persistence.createEntityManagerFactory(String persistenceUnitName, Map properties), but somehow it does not honours caching.

I don't get the link between validation and caching. If you do a facade to the entity manager tenant aware you just have caching per entity manager which means you will not check local cache for production persistence unit.
If you want a single entity manager - =you'll get a single JPA cache in this mode which will merge local and production - you can use dynamic routing: http://tomee.apache.org/examples-trunk/dynamic-datasource-routing/README.html instead of dynamic persistence units.

Related

Hibernate connections strange behavior

We are making a web application where we are using PayPal for the users to make a subscription but we are having some problems. When we are creating accounts, logging in and doing various requests we have no problems but when we are making 4-7 simultaneous payments our connection pool is not behaving properly.
This is an image of the number of connections. You can see the number of connections spikes after a few payments. When we reset the server it drops down. The last time where the connections are high, you can see what's happening when the server gets to take care of the connection itself -
as you can see it takes hours to drop connections.
This is our persistence.xml:
<?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="up2u">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/up2u_user?autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="up2u_user2"/>
<property name="hibernate.connection.password" value="e2f2c2ac87"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="true"/>
<!-- Connectionpool-->
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
<property name="hibernate.c3p0.max_size" value="200" />
<property name="hibernate.c3p0.min_size" value="10" />
<property name="hibernate.c3p0.max_statements" value="400" />
<property name="hibernate.c3p0.acquireIncrement" value="10"/>
<property name="hibernate.c3p0.acquireRetryAttempts" value="3"/>
<property name="hibernate.c3p0.acquireRetryDelay" value="100"/>
<property name="hibernate.c3p0.checkoutTimeout" value="300" />
<property name="hibernate.c3p0.timeout" value="300" />
<property name="hibernate.c3p0.idle_test_period" value="300" />
<property name="hibernate.c3p0.idleConnectionTestPeriod" value="300" />
<property name="hibernate.c3p0.maxConnectionAge" value="300" />
<property name="hibernate.c3p0.maxStatementsPerConnection" value="2" />
<property name="hibernate.c3p0.testConnectionOnCheckin" value="true"/>
</properties>
</persistence-unit>
</persistence>
Why is the number connections not dropping when doing payments? The CPU and memory aren't working significantly more when doing payments and I can see nothing more than the connections building and a few more packets/second in firewall throughput.

Properly Refresh data from Database JPA - Hibernate

I'm currently using the JPA specs to query my objects from the database.
Everytime there's a change made by me (my instance of the software), the items would be properly refreshed.
But, if there's another change made by someone else (other instance, or database change), the items are'nt being properly refreshed.
I'm using a simple "find" with "refresh"
Object found = getManager().find(getModelClass(), id);
getManager().refresh(found);
I'm using a DAO Hierarchy, the "getModelClass" returns my #Entity class like
#Override
protected Class<?> getModelClass() {
return ProductCategory.class;
}
And my Manifest / persistence.xml:
<?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="casa" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<!-- localhost -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/database" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.use_sql_comments" value="false" />
<property name="hibernate.jdbc.wrap_result_sets" value="false" />
<property name="hibernate.hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
Also each "DAO" have and instance of and EntityManager of it's own.
What I might be doing wrong ?
Appreciate the help!
Seems like my problem was simple.
The refresh transaction to be properly refreshed from the database needs to be commited
getManager().getTransaction().begin();
T found = (T) getManager().find(getModelClass(), id);
getManager().refresh(found);
getManager().getTransaction().commit();

Hibernate with Glassfish 4.1

I've setted up Hibernate on Glassfish 4.1 but I'm having problems with persistence.
I'm able to read data, but cannot write to BD (changes appear to not be commited).
My current persistent.xml looks 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://java.sun.com/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="myPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/myDataSource</jta-data-source>
<properties>
<property name="transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManagerLookup"/>
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2008Dialect"/>
</properties>
</persistence-unit>
</persistence>
My connection pool config on Glassfish is:
<jdbc-connection-pool datasource-classname="com.microsoft.sqlserver.jdbc.SQLServerDataSource" steady-pool-size="2" name="myPool" res-type="javax.sql.DataSource">
<property name="TrustServerCertificate" value="false"></property>
<property name="User" value="sa"></property>
<property name="LastUpdateCount" value="true"></property>
<property name="ResponseBuffering" value="adaptive"></property>
<property name="URL" value="jdbc:sqlserver://server\bd"></property>
<property name="XopenStates" value="false"></property>
<property name="PacketSize" value="8000"></property>
<property name="Password" value="mypass"></property>
<property name="ApplicationName" value="Microsoft JDBC Driver for SQL Server"></property>
<property name="DatabaseName" value="MyDB"></property>
<property name="Encrypt" value="false"></property>
<property name="LockTimeout" value="-1"></property>
<property name="SendStringParametersAsUnicode" value="true"></property>
<property name="MultiSubnetFailover" value="false"></property>
<property name="ApplicationIntent" value="readwrite"></property>
<property name="LoginTimeout" value="15"></property>
<property name="WorkstationID" value="My-MacBook-Pro.local"></property>
<property name="ServerName" value="xpto"></property>
<property name="PortNumber" value="1433"></property>
<property name="SelectMethod" value="direct"></property>
<property name="SendTimeAsDatetime" value="true"></property>
</jdbc-connection-pool>
Datasource config:
<jdbc-resource pool-name="myPool" jndi-name="jdbc/myDataSource"></jdbc-resource>
My EJB looks like this:
#PersistenceContext
private EntityManager em;
public void updateUser(User u) {
em.merge(u);
}
Any idea how I can fix that?
Thanks!
In my case, I was running the Hibernate 5 with tomcat and stop working when I changed to glassfish 4.1
The reason was the oldest jboss-logging.jar at: "YOUR_GLASSFISH_FOLDER/glassfish/modules"
Why? The hibernate 5 has dependency with the newest version of jboss-logging, and the glassfish uses the oldest version even if you declare inside your POM file the newest version. Actually I'm using:
org.jboss.logging jboss-logging 3.3.0.Final
Then I downloaded and replace the old .jar inside modules path and back to work, I spent 2 days trying to solve that and I hope it helps some future issues =D
I used this link to help me: https://medium.com/#mertcal/using-hibernate-5-on-payara-cc242212a5d6#.npq2hdprz
Could you please try the following configuration:
<?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="YOUR_PERSISTANCE_NAME" transaction-type="RESOURCE_LOCAL">
<provider>YOUR_PROVIDER</provider>
<!-- ENTITIES -->
<class>com.company.project....EntityA</class>
<class>com.company.project....EntityB</class>
<class>com.company.project....EntityC</class>
<properties>
<property name="javax.persistence.jdbc.url" value="YOUR_URL_TO_DB" />
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.user" value="USER" />
<property name="javax.persistence.jdbc.password" value="PASS" />
<property name="eclipselink.logging.level" value="INFO" />
<property name="eclipselink.target-database" value="PostgreSQL" />
</properties>
</persistence-unit>

Verify c3p0 running with JPA

I'm using JPA for my persistence for my project and don't really know anything about hibernate but most tutorials I follow have found to setup connection pooling use c3p0 and hibernate.
Heres 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="Cinemango308PU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>JPA.Ad</class>
<class>JPA.Photo</class>
<class>JPA.Theatre</class>
<class>JPA.Creditcard</class>
<class>JPA.Moviereview</class>
<class>JPA.Giftcard</class>
<class>JPA.Showtime</class>
<class>JPA.Ticket</class>
<class>JPA.Favoritetheatres</class>
<class>JPA.User</class>
<class>JPA.Actor</class>
<class>JPA.Movie</class>
<class>JPA.Theatrerewards</class>
<class>JPA.Payment</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:5432/cinemango>
<property name="javax.persistence.jdbc.user" value="xxxx"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value="xxxxxx"/>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<!-- Configuring Connection Pool -->
<property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
<property name="hibernate.c3p0.max_size" value="5" />
<property name="hibernate.c3p0.min_size" value="0" />
<property name="hibernate.c3p0.acquire_increment" value="1" />
<property name="hibernate.c3p0.idle_test_period" value="300" />
<property name="hibernate.c3p0.max_statements" value="0" />
<property name="hibernate.c3p0.timeout" value="100" />
</properties>
</persistence-unit>
</persistence>
How do i test if the connection pooling is working? I don't see a log displayed to my output
Please find the logging configuration here http://www.mchange.com/projects/c3p0/#configuring_logging
There you can find how to switch on debug to see if pooling happens.

How to qualify sequence names in Hibernate?

I'm having troubles when generating sequences for an oracle databese running under the same instance than other one, with the same data structure. Here is a fragment of my persistence.xml where I define different schemas according to the persistence unit:
<persistence-unit name="oracle_development" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.ejb.entitymanager_factory_name"
value="o11g" />
<property name="hibernate.default_schema" value="devdatabase"/>
</properties>
</persistence-unit>
<persistence-unit name="oracle_production" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.ejb.entitymanager_factory_name"
value="o11g" />
<property name="hibernate.default_schema" value="proddatabase"/>
</properties>
</persistence-unit>
Well, the tables are generated perfectly, once the table names in creating commands include the default schema as qualifier. But sequences are not generated in the 'proddatabase' if they're already created on 'devdatabase', in example... Any help?
The hibernate.hbm2ddl.auto=”update” is convenient but less flexible if you plan on adding functions or executing some custom scripts.
So, the most flexible approach is to generate the DDL scripts with "org.hibernate.tool.ant.HibernateToolTask" and then use a component to execute the scripts on context startup. The destroy scripts are called when the Spring context is closed.
The second approach is much more flexible, especially if you want to mix JPA Entity Model with jOOQ Table Model.
Needless to say that this is only an Integration testing concern since for the production environment we use Flyway. So, you shouldn't rely on Hibernate for managing your database schema, because it's riskier, less flexible and it doesn't play well with CI and CD.

Categories