In persistence.xml I am creating a database (in-memory database for test) like this:
<persistence-unit name="TestDatabase" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jar-file>pathToMyJar.jar</jar-file>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.archive.autodetection" value="class, hbm" />
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties>
</persistence-unit>
That works as expected but is slow. So I saved a sql-script for schema generation like this:
<persistence-unit name="TestDatabase" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jar-file>pathToMyJar.jar</jar-file>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.archive.autodetection" value="class, hbm" />
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="javax.persistence.schema-generation.scripts.action" value="create"/>
<property name="javax.persistence.schema-generation.scripts.create-target" value="pathToSchemaGeneratonScript.sql"/>
</properties>
</persistence-unit>
And then tried to use it like this:
<persistence-unit name="TestDatabase" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.show_sql" value="true" />
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="javax.persistence.schema-generation.create-source" value="script"/>
<property name="javax.persistence.schema-generation.create-script-source" value="pathToSchemaGeneratonScript.sql"/>
</properties>
</persistence-unit>
Since show_sql is set to true I can see that the script runs, e.g "create table xxx (...".
But no tables seems to exist, e.g:
entityManagerFactory = Persistence.createEntityManagerFactory("TestDatabase");
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
Query query = entityManager.createNativeQuery("insert into xxx (someColumns) values (someValues)");
query.executeUpdate();
Will result in "org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Table "xxx" not found".
I have connected manually and verified that the tables are not there. I also applied the generated sql file manually and then the tables are created as expected.
Related
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.
I am using hibernates entityManager to delete an object. However the object is not getting deleted even after flushing the entityManager. It is getting returned if I do a find on it using is id.
Following is what my piece of code looks like:
#PersistenceContext(unitName = "registryPU")
private EntityManager em;
public <E> E delete(Class<E> clazz, String id) {
E en=(E) find(clazz, id);
if(en != null){
em.remove(en);
em.flush();
}
en=(E) find(clazz, id);
assert ( en == null);
return en;
}
public <E> E find(Class<E> clazz, String id) {
return em.find(clazz, id);
}
and the persistence.xml is as follows:
<persistence-unit name="registryPU"
transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<validation-mode>CALLBACK</validation-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.import_files" value="import.sql"/>
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
<property name="hibernate.event.merge.entity_copy_observer" value="allow"/>
</properties>
</persistence-unit>
</persistence>
This should ideally work fine, but is throwing java.lang.AssertionError because of the assert statement. Can someone let me know what is wrong in this and how to avoid it ?
Try to use this after remove(), but before flush()
em.getTransaction().commit();
Can't see <jta-data-source> entry in your persistence.xml. Try adding it as below:
<persistence-unit name="registryPU"
transaction-type="JTA">
<jta-data-source>jdbc/sample</jta-data-source>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<validation-mode>CALLBACK</validation-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.import_files" value="import.sql"/>
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
<property name="hibernate.event.merge.entity_copy_observer" value="allow"/>
</properties>
</persistence-unit>
</persistence>
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.
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.
I need persistence unit that creates embedded database which stays persistent after closing EntityManager.
This is my PU:
<persistence-unit name="hello-jpa" transaction-type="RESOURCE_LOCAL">
<class>hello.jpa.User</class>
<properties>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:target/hsql.db"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
And it deletes data after closing application.
My understanding of the documentation is that the "old" URL jdbc:hsqldb:. creates or connects to the same database as the new form for the URL jdbc:hsqldb:mem:. (i.e. in memory).
So try with the following URL instead: jdbc:hsqldb:file:target/hsql.db.