unit testing: jpa, hibernate - how to handle entity managers? - java

I have a test class for a programme that uses jpa/hibernate, the dao pattern, controller classes and a gui - the usual.
I have written a persistence.xml that contains persistence-units for both the main and the test classes:
<persistence 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"
version="2.0">
<persistence-unit name="com.to.me.project.main"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/database" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="" />
<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" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.id.new_generator_mappings" value="true"/>
<!-- <property name="hibernate.generate_statistics" value="true" /> -->
</properties>
</persistence-unit>
<persistence-unit name="com.to.me.project.test"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:unit-testing" />
<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
Works fine in production code and when I run the test, the right persistence configuration is found and the databases are created.
My programme works like this: the controller calls a method of the DAO (such as create) and in this method, I get the entitymanager and use its methods (such as persist):
#Override
public void create(final SomeEntity object) throws DAOException {
EntityManager em = MyPersistenceManager.getEntityManager();
em.getTransaction().begin();
em.persist(objekt);
em.getTransaction().commit();
em.close();
}
(The PersistenceManager is my own class, a wrapper around the EntityManagerfactory and so on...)
The problem: That entity manager uses the persistence-unit configs for the main-classes, i. e. the mysql database.So when I run my test and call the controller, it doesnt use the hsqldb databases I set up.
How do I test my controller logic with the configurations for the test persistence unit, i. e. the hsqldb?

Related

JPA/Hibernate: How to scan particular package in Persistence.xml in place of giving single entity name?

I have 10 entities in package:
com.paka.maka.raka
I have 5 entities in package
com.paka
I only want to scan 10 entities in first package name.
Is it mandatory to name whole classes or is there way to give package name only to scan in Persistance.xml
<persistence-unit name="IntegratorMasterdataPU" transaction-type="RESOURCE_LOCAL" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:#dat-esb-orat:1521/rator_test" />
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.connection.username" value="DATA" />
<property name="hibernate.connection.password" value="264rcxx" />
<!--QA <property name="hibernate.connection.password" value="emifuqqgqn5" /> -->
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<!-- <property name="hibernate.hbm2ddl.auto" value="create" /> -->
</properties>
</persistence-unit>
I'm not pretty sure it will work, but you can use:
<property name="packagesToScan" value="com.paka.maka.raka"/>
In your entityManagerFactory bean declaration
Check this post

No Persistence provider for EntityManager in prod more

I've been making an app using Play Framework 2.5 and I had no problems while running it in dev mode with run command, but once I try to switch to prod mode I am having this exception:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named defaultPersistenceUnit
my persistence.xml is in conf/META-INF/ folder
<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="defaultPersistenceUnit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>DefaultDS</non-jta-data-source>
<class>models.entities.Artifact</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="current_session_context_class" value="thread" />
</properties>
</persistence-unit>
<persistence-unit name="testPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<class>models.entities.Artifact</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.user" value="" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="show_sql" value="false" />
<property name="hibernate.temp.use_jdbc_metadata_defaults"
value="false" />
</properties>
</persistence-unit>
Please give me at least some clues to where the problem might be

Spring mvc multiple entities database persistance

I'm having troubles with "working with multiple databases" in Spring MVC - hibernate JPA
I have two databases called user_db and portal_db. I need to work with them in different jpa units.
here is my persistance.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence 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" version="1.0">
<persistence-unit name="user_unit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Package.Entity1</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost/user_db" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.username" value="postgres" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
<!--<property name="hibernate.hbm2ddl.auto" value="create-drop" />-->
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
<persistence-unit name="portal_unit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Package.Entity2</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost/portal_db" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.username" value="postgres" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
<!--<property name="hibernate.hbm2ddl.auto" value="create-drop"/>-->
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
Problem is When I use create-drop and run my project, it creates both of my entites in both databases. Like table that should be only created by Package.Entity1 in user_unit, is also created in portal_unit.
And when I select,insert,update my entites, I set persistance unit in each of my individual DAO's.
for example, in Entity Dao's implementation I have:
EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit);
where persistenceUnit could be user_unit or portal_unit depending on implementation.
What changes should I make so it wont create same table in both databases?
Add <exclude-unlisted-classes>true</exclude-unlisted-classes> in both of yours persistence units OR use JPA 2.x
Add <exclude-unlisted-classes>true</exclude-unlisted-classes> in both your persistence units.
Please follow post below for detailed explanation:
Multiple persistance unit in persistence.xml creating tables in one another

how to create session and fire query in jpa

I am novice in JPA 2.0.
Can someone tell me the steps how to create a new session and then execute query in JPA ?
Please do needful.
I hope you have created a persistence.xml with a persistence unit tag. If you haven't then you need one here is the example
<?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="JPASamplePU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.cksoft.jpasample.entity.Person</class>
<class>org.cksoft.jpasample.entity.Profile</class>
<class>org.cksoft.jpasample.entity.Department</class>
<class>org.cksoft.jpasample.entity.Skills</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/MyApp_DB" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<!-- <property name="hibernate.cache.use_second_level_cache" value="true"
/> -->
<!-- <property name="hibernate.cache.use_query_cache" value="true" /> -->
</properties>
</persistence-unit>
</persistence>
After that you need to create EntityManagerFactory (if you are accessing it from main method)
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PERSISTENCE_UNIT_NAME");
EntityManager em = emf.createEntityManager();
Here is how we can get a transaction and begin it and commit it.
em.getTransaction().begin();
em.getTransaction().commit();
After this you can keep using the EntityManager or close it
em.close();
Session is hibernate specific class which is almost as equal as EntityManager.
Correct me guys if I am wrong or something is missing thank you.

Hibernate don't update entity after changing something directly in database?

Hi all I have pretty strange problem let me first show my configuration etc. Here is persitance.xml:
<persistence-unit name="allegroTransactionPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/AllegroShop?UseUnicode=true&characterEncoding=utf8" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="topSecret" />
<property name="hibernate.connection.password" value="topSecret" />
<!-- <property name="hibernate.hbm2ddl.auto" value="create" /> -->
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="show_sql" value="true" />
<property name="hibernate.hbm2ddl.import_files" value="/SQL/payment_type.sql"/>
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />
</properties>
</persistence-unit>
And here is method that I use to take data from my database:
#PersistenceContext( unitName = "allegroTransactionPersistenceUnit", type= PersistenceContextType.EXTENDED )
protected EntityManager em;
public List<AllegroTransactionImpl> readAllegroTransactionByCreateDate()
{
TypedQuery<AllegroTransactionImpl> query = this.em.createQuery( "SELECT allegroTransaction FROM com.springapp.mvc.classes.AllegroTransactionImpl allegroTransaction ORDER BY createDate DESC", AllegroTransactionImpl.class);
return query.getResultList();
}
And now the problem. Everything works great if I use hibernate to update / delete / add. but if I change some value directly in base (by SQL statement) hibernate don't refresh it question is why ?
Entity class
https://gist.github.com/spec8320/144100f049f54b73ad86
please make sure you had committed the change by SQL statement.
please check if you have enabled the 2nd level cache on AllegroTransactionImpl

Categories

Resources