Spring Boot JPA Hibernate + persistence.xml Not Inserting - spring

I am having an issue with inserts not working. Reads (Selects) work okay. However, an insert is not being executed at end of my #Transactional method. Even though I do see the Transaction commit/close being called on the Entity Manager. I have tried different configurations and I still cannot get records (inserts) to work at the end of a transaction. And I don't see any errors being generated. I enabled the hibernate.transaction DEBUG and I don't see any hibernate transaction messages.
I am running Spring boot (.1.5.3) as a WAR executable with Tomcat. I am using persistence.xml (which is required by hibernate5-ddl-maven-plugin< to generate the SQL DDL during the build) on Spring Boot.
While debugging, I saw the JpaTransactionManager creating new transaction (Creating new transaction with name... Opened new EntityManager ,,,Exposing JPA transaction as JDBC transaction), joining other #Transactional methods (Found thread-bound EntityManager... Participating in existing transaction) and committing TX (Initiating transaction commit... Committing JPA transaction on EntityManager), and closing the JPA EM (Closing JPA EntityManager). This all happens according to the #Transactional specs. However, the record is not inserted into to the database. And I don't see any hibernate transaction messages.
Below is some of my configuration.
persistence.xml:
<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">
<!--
This file is needed to generate the DDL.
-->
<persistence-unit
name="EzListaPersistence"
transaction-type="RESOURCE_LOCAL">
<description>
The set of entity types that can be managed by a
given entity manager is defined by a persistence unit. A
persistence unit defines the set of all classes that are
related or grouped by the application, and which must be
collocated in their mapping to a single data store.
</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!--
List of fully qualified Entity Classes
-->
<class>com.ezlista.domain.account.Account</class>
...... NOT DISPLAYED ....
<class>com.ezlista.domain.useraccount.Notification</class>
<properties>
<!-- Hibernate Connection Settings -->
<property
name="hibernate.connection.provider_class"
value="org.hibernate.hikaricp.internal.HikariCPConnectionProvider" />
<property
name="hibernate.hikari.dataSourceClassName"
value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
<property
name="hibernate.hikari.dataSource.url"
value="jdbc:mysql://localhost:3306/EZLISTA?verifyServerCertificate=false&useSSL=false" />
<property
name="hibernate.hikari.dataSource.user"
value="rubens" />
<property
name="hibernate.hikari.dataSource.password"
value="***MASKED***" />
<property
name="hibernate.hikari.dataSource.cachePrepStmts"
value="true" />
<property
name="hibernate.hikari.dataSource.prepStmtCacheSize"
value="250" />
<property
name="hibernate.hikari.dataSource.prepStmtCacheSqlLimit"
value="2048" />
<property
name="hibernate.hikari.minimumIdle"
value="5" />
<property
name="hibernate.hikari.maximumPoolSize"
value="10" />
<property
name="hibernate.hikari.idleTimeout"
value="30000" />
<!-- SQL Settings -->
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.show_sql"
value="false" />
<property name="hibernate.format_sql"
value="true" />
<property name="hibernate.use_sql_comments"
value="false" />
<property name="hibernate.ddl-auto"
value="none" />
<!-- Hibernate Cache Settings -->
<property name="hibernate.javax.cache.provider"
value="org.ehcache.jsr107.EhcacheCachingProvider" />
<property name="hibernate.cache.region.factory_class"
value="org.hibernate.cache.jcache.JCacheRegionFactory" />
<property name="hibernate.cache.use_second_level_cache"
value="true" />
<property name="hibernate.cache.use_query_cache"
value="false" />
<property name="hibernate.cache.use_structured_entries"
value="true" />
<property name="hibernate.cache.use_minimal_puts"
value="true" />
</properties>
</persistence-unit>
Java Configuration:
#EntityScan("com.ezlista.domain")
#EnableTransactionManagement
/**
* Spring Bootstrap Repository Configuration.
*
* #author Rubens Gomes
*/
#Configuration
public class RepositoryConfiguration
{
private final static Logger logger = LoggerFactory.getLogger(RepositoryConfiguration.class);
private final static String PERSISTENCE_UNIT = "EzListaPersistence";
#Inject
private Environment env;
public RepositoryConfiguration()
{
super();
logger.debug("Constructed");
}
// DataSource
#Bean(name = "dataSource")
public DataSource dataSource()
{
logger.info("Registering HikariDataSource bean.");
HikariDataSource ds = new HikariDataSource();
ds.setDataSourceClassName(env.getRequiredProperty("hikari.dataSourceClassName"));
ds.setMinimumIdle(env.getRequiredProperty("hikari.minimumIdle", Integer.class));
ds.setMaximumPoolSize(env.getRequiredProperty("hikari.maximumPoolSize", Integer.class));
ds.setIdleTimeout(env.getRequiredProperty("hikari.idleTimeout", Integer.class));
ds.setPoolName(env.getRequiredProperty("hikari.poolName"));
ds.addDataSourceProperty("user", env.getRequiredProperty("hikari.dataSource.user"));
ds.addDataSourceProperty("password", env.getRequiredProperty("hikari.dataSource.password"));
ds.addDataSourceProperty("databaseName", env.getRequiredProperty("hikari.dataSource.databaseName"));
ds.addDataSourceProperty("serverName", env.getRequiredProperty("hikari.dataSource.serverName"));
ds.addDataSourceProperty("cachePrepStmts", env.getRequiredProperty("hikari.dataSource.cachePrepStmts", Boolean.class));
ds.addDataSourceProperty("prepStmtCacheSize", env.getRequiredProperty("hikari.dataSource.prepStmtCacheSize", Integer.class));
ds.addDataSourceProperty("prepStmtCacheSqlLimit", env.getRequiredProperty("hikari.dataSource.prepStmtCacheSqlLimit", Integer.class));
return ds;
}
// EntityManagerFactory
#Bean(name = "entityManagerFactory")
public EntityManagerFactory entityManagerFactory()
{
logger.info("Registering EntityManagerFactory bean.");
JpaVendorAdapter hibernateJpavendorAdapter = new HibernateJpaVendorAdapter();
JpaDialect hibernateJpaDialect = new HibernateJpaDialect();
LocalContainerEntityManagerFactoryBean emfBean =
new LocalContainerEntityManagerFactoryBean();
emfBean.setJpaVendorAdapter(hibernateJpavendorAdapter);
emfBean.setJpaDialect(hibernateJpaDialect);
emfBean.setPersistenceUnitName(PERSISTENCE_UNIT);
emfBean.setDataSource(dataSource());
emfBean.afterPropertiesSet();
return emfBean.getObject();
}
// TransactionManager
#Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager()
{
logger.info("Registering JpaTransactionManager bean.");
JpaTransactionManager txManager = new JpaTransactionManager();
EntityManagerFactory emf = entityManagerFactory();
txManager.setEntityManagerFactory(emf);
txManager.setDataSource(dataSource());
return txManager;
}
}

Bingo!!!!
I annotated my EntityManager with #PersistenceContext(unitName = PERSISTENCE_UNIT_NAME). After that it works.
Here is the code that fixed the above problem. Notice the #PersistenceContext annotation below (that's what fixed the issue). Before I had #Inject annotation on the em.
#PersistenceContext(unitName = PERSISTENCE_UNIT_NAME)
protected EntityManager em;

Related

Spring batch doesnt start transaction when using custom writer

I am working on a spring batch which reads from a csv file and writes into database. i am using FlatFileItemReader for reading the file and implemented ItemWriter which uses Jpa to insert data into database. But batch fails with no transaction in progress.
Here is my job configuration
<bean id="datasource" class="oracle.jdbc.pool.OracleDataSource">
<property name="user" value="xxx" />
<property name="password" value="xx" />
<property name="URL" value="xxx" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory" name="model"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="datasource"/>
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false"/>
<property name="showSql" value="true"/>
<property name="database">
<util:constant
static-field="org.springframework.orm.jpa.vendor.Database.ORACLE"/>
</property>
<property name="databasePlatform" value="org.hibernate.dialect.Oracle12cDialect"/>
</bean>
</property>
</bean>
<batch:job id="testJob">
<batch:step id="step">
<batch:tasklet>
<batch:chunk reader="cvsFileItemReader" writer="databaseWriter"
commit-interval="10">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
And below is my writer
public class DatabaseWriter implements ItemWriter<Report> {
private EntityManagerFactory entityManagerFactory;
#Autowired
public DatabaseWriter(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
#Override
public void write(List<? extends Report> list) throws Exception {
EntityManager entityManager = entityManagerFactory.createEntityManager();
for (Report report : list) {
entityManager.persist(report );
}
entityManager.flush();
}
}
It only works if start transaction explicitly .that is like below
public class DatabaseWriter implements ItemWriter<Report> {
private EntityManagerFactory entityManagerFactory;
#Autowired
public DatabaseWriter(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
#Override
public void write(List<? extends Report> list) throws Exception {
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
for (Report report : list) {
entityManager.persist(report );
}
entityManager.getTransaction().commit();
}
}
Is it really needed that transaction should be maintained explicitly and spring batch doesn't control it out of box?
EDIT
I fixed it by changing writer like
public class DatabaseWriter implements ItemWriter<Report> {
#PersistenceContext
private EntityManager entityManager;
#Override
public void write(List<? extends Report> list) {
for (Report report : list) {
entityManager.persist(report );
}
}
Changing EntityMangerFactory to EntityManager with PersistenceContext fixed the problem. But i am struggling to understand reason for this behaviour
Create DAO and move your JPA code there and autowire the DAO in your writer.
Also make sure you autowire the entity manager like below.
#PersistenceContext
private EntityManager em;
But i am struggling to understand reason for this behaviour
The first approach does not work because you create a transaction manually while your code is actually running within the scope of a transaction driven by Spring Batch. So there will be two transactions with different contexts.
You should keep in mind that a tasklet is executed in a transaction driven by Spring Batch (including the item writer for a chunk-oriented tasklet). So any code running in that scope should conform to the transaction definition of the tasklet. In your case, the EntityManager injected in the writer is driven by the JpaTransactionManager you defined, which is also used by Spring Batch for the tasklet's transaction.
As a side note, you can use the JpaItemWriter provided by Spring Batch instead of writing a custom writer. The code is almost identical.

Connection pool replacement for already implemented Spring Jdbctemplate project

I am a doing a mid size project with spring jdbc and MsSQL server , project is almost 50% done , now when every request doing lots of inserts and updates specially with those tables which contains lots of columns and large datasets is performing very slow , and sometimes showing connection closed.
Now i am thinking to integrate C3p0 or similar connection pooling but i cant change any DAO code which i already done ..
I implemented a DAOHelper class with JDBCTemplate variable and injecting the JDBCTemplate dependency in applicationContext.xml with autowiring of DAOClass in controller class , and i extended this DAOHelper to all DAO classes and using this jdbcTemplate to do JDBC operations.
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="jdbc:sqlserver://192.168.1.101:1433;databaseName=OrderManager"/>
<property name="username" value="sa"/>
<property name="password" value="520759"/>
</bean>
<bean id="JdbcDataSource" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"/>
</bean>
<bean id="OrderDAO" class="com.ordermanager.order.dao.OrderDAO" >
<property name="jdbcTemplate" ref="JdbcDataSource"/>
<property name="transactionManager" ref="transactionManager"/>
</bean>
#Controller
public class OrderController {
#Autowired
OrderDAO orderDAO;
#RequestMapping(value = "/addNewItem", method = RequestMethod.GET)
public ModelAndView addItem(#RequestParam("ParamData") JSONObject paramJson) {
ApplicationContext ctx = new FileSystemXmlApplicationContext(ConstantContainer.Application_Context_File_Path);
OrderDAO orderDAO = (OrderDAO) ctx.getBean("OrderDAO");
return new ModelAndView("MakeResponse", "responseValue", orderDAO.addItem(paramJson));
}
public class DAOHelper {
private JdbcTemplate jdbcTemplate;
private PlatformTransactionManager transactionManager;
public PlatformTransactionManager getTransactionManager() {
return transactionManager;
}
public void setTransactionManager(PlatformTransactionManager txManager) {
this.transactionManager = txManager;
}
public JdbcTemplate getJdbcTemplate() /*I am using this Method for all JDBC Task*/ {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
Now with minimal code changes how can i integrate C3p0 or any good connection pooling library with my already written code.
Just change the ds bean in your config xml with following and consider adding other c3p0 properties according to your own. make sure to have c3p0 jar in your classpath.
<bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="jdbcUrl" value="jdbc:sqlserver://192.168.1.101:1433;databaseName=OrderManager" />
<property name="user" value="sa" />
<property name="password" value="520789" />
</bean>

Spring & Hibernate - Make native queries run in the same transaction as #Transactional

Is it possible to create native queries that make use of an existing transaction created via #Transactional?
Most of the questions here seem to be about making native queries at all. Also, answers such as the one from Spring + Hibernate Transaction -- Native SQL rollback failure suggest it might not be possible.
What I do to test the isolation is to run some deletes and add a breakpoint to investigate the database.
Here is what I tried so far:
#Transactional(value = "someManager")
public class SpringJpaSomeDao implements SomeDao {
#PersistenceContext(unitName = "someUnit")
#Qualifier("entityManagerFactorySome")
private EntityManager em;
#Resource
#Qualifier("someManager")
private PlatformTransactionManager transactionManager;
#Override
#Transactional(value = "someManager", propagation = Propagation.SUPPORTS)
public void runNative(String sql){
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
em.createNativeQuery(sql).executeUpdate();
}
});
}
Some part of the persistence.xml
<persistence-unit name="someUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>java:comp/env/jdbc/someDS</non-jta-data-source>
<!-- some classes here -->
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<!-- some dialect -->
</properties>
</persistence-unit>
The code is invoked from some controller which also has #Transactional annotations giving the deletes to the Dao.
#Transactional(value = "someManager", propagation = Propagation.SUPPORTS)
public void deleteEntireDatabase() {
List<String> deletions = new ArrayList<>();
deletions.add("DELETE FROM something;");
for (String currentDeletion : deletions) {
someDao.runNative(currentDeletion);
}
}
#Override
#Transactional(value = "someManager", propagation = Propagation.REQUIRES_NEW, rollbackFor = {Exception.class})
public void deleteAndFill(JobExecutionProgress progress) {
deleteEntireDatabase();
// more code
}
Excerpt from spring-dao.xml:
<tx:annotation-driven />
<bean id="entityManagerFactorySome" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="someDataSource" />
<property name="persistenceUnitName" value="someUnit" />
<property name="jpaProperties">
<props>
<!-- some dialect -->
</props>
</property>
</bean>
<bean id="someDao" class="xyz.model.controller.SpringJpaSomeDao"/>
<bean id="someManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactorySome" />
<qualifier value="someManager"></qualifier>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
Of course, I also tried some variations such as different Propagations, and using the entityManager obtained from elsewhere:
EntityManagerFactory emf = ((JpaTransactionManager) transactionManager).getEntityManagerFactory();
EntityManager em2 = EntityManagerFactoryUtils.getTransactionalEntityManager(emf);
Now, what I will do if everything else fails is manual transaction management.
Is this something that has worked for one of your applications or is it unknown if this might be a setup problem?
Actually, it turns out the alter table statements mentioned in the comment seem to have been the problem. Not sure how resetting the auto_increment can empty the table, but that seemed to be the case.

JPA entityMangerFactory not found through Persistence.createEntityManagerFactory("XYZ")

Any help will be greatly appreciated.
We are working on a web application. Which uses a JAR file (a java maven project) and has been added as a maven dependency in the web application.
Combination of this JAR file and web application itself creating problem.
Both web application and JAR are using Hibernate JPA to interact with database. But both are using 2 different ways for creating/initializing entityManagerFactory.
Web Application uses Spring xml based configuration to initialize entityManagerFactory.
CODE:
persistence.xml code:
<persistence-unit name="org.jbpm.persistence.jpa.local"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>META-INF/JBPMorm-JPA2.xml</mapping-file>
<class>org.drools.persistence.info.SessionInfo</class>
<class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
Spring configuration:
<context:component-scan base-package="com.company.rd.core" />
<context:component-scan base-package="com.company.rd.services" />
<jee:jndi-lookup id="testDataSource" jndi-name="java:comp/env/jdbc/SybaseDB" />
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="testDataSource"/>
<property name="defaultTimeout" value="120"></property>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="org.jbpm.persistence.jpa.local" />
<property name="dataSource" ref="testDataSource" />
<property name="jpaDialect" ref="jpaDialect" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="jpaDialect" ref = "jpaDialect"></property>
<property name="defaultTimeout" value="120"></property>
</bean>
<jee:jndi-lookup id="logDataSource" jndi-name="java:comp/env/jdbc/DRMLOG" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
And Here is the code to initializing entitymanagerFactory in JAR file.
persistence.xml
<persistence-unit name="codeAuthorization" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>java:/comp/env/jdbc/SybaseDB</non-jta-data-source>
<class>com.company.auth.entity.AuthorizationCode</class>
<class>com.company.auth.entity.UserInvalidAttempt</class>
<class>com.company.auth.entity.AuthorizationProperty</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
And a java file which is injected into Base DAO through spring.
#Service
public class AuthorizationEntityMangerService {
#PersistenceUnit(name = "codeAuthorization")
private EntityManagerFactory entityManagerFactory;
public AuthorizationEntityMangerService() {
entityManagerFactory = Persistence
.createEntityManagerFactory("org.jbpm.persistence.jpa.local");
}
public EntityManagerFactory getEntityManagerFactory() {
return entityManagerFactory;
}
public EntityManager getEntityManager() {
return this.entityManagerFactory.createEntityManager();
}
public void closeEntityManager(EntityManager entityManager) {
if (entityManager != null && entityManager.isOpen()) {
entityManager.close();
}
}
public EntityTransaction getTransaction(EntityManager entityManager) {
return entityManager.getTransaction();
}
public void rollBackTransaction(EntityTransaction transaction) {
if (transaction != null && transaction.isActive()) {
transaction.rollback();
}
}
public void commitTransaction(EntityTransaction transaction) {
if (transaction != null && transaction.isActive()) {
transaction.commit();
}
}
}
Calling code from Base DAO.
public Object getSingleResult(final String queryString, final String key,
final NamedQueryParameter namedQueryParameter) {
EntityTransaction transaction = null;
EntityManager entityManager = null;
try {
entityManager = this.entityMangerService.getEntityManager();
transaction = entityMangerService.getTransaction(entityManager);
transaction.begin();
final Query query = entityManager.createQuery(queryString);
setQueryParameter(query, namedQueryParameter);
final Object result = query.getSingleResult();
entityMangerService.commitTransaction(transaction);
return result;
} catch (final NoResultException e) {
entityMangerService.rollBackTransaction(transaction);
logger.error("Error" : " + e.getMessage());
return null;
} finally {
entityMangerService.closeEntityManager(entityManager);
}
}
Now Here is the problem when ever line entityManager.createQuery(queryString); execute it throws the exception.
2015-06-05 17:39:46,363 WARN DefaultExceptionHandler:94 - Unhandled exception caught by the Stripes default
exception handler.
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: AuthorizationProperty is
not mapped [SELECT pe.value FROM AuthorizationProperty pe WHERE pe.name=:propertyName AND pe.deleted=0]
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1364)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:294)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke
(ExtendedEntityManagerCreator.java:334)
at com.sun.proxy.$Proxy53.createQuery(Unknown Source)
at com.company.authentication.dao.AuthorizationBaseDAO.getSingleResult(AuthorizationBaseDAO.java:40)
at com.company.authentication.dao.PropertyDAOImlp.getPropertyValue(PropertyDAOImlp.java:22)
at com.company.authentication.services.AuthorizationPropertyService.getPropertyValueByName
(AuthorizationPropertyService.java:19)
at com.company.rd.servlet.JspAuthorizationRestFilter.hasAuthorizationCode
(JspAuthorizationRestFilter.java:105)
at com.company.rd.servlet.AbstractAuthorizationRestFilter.isRequestAuthenticated
(AbstractAuthorizationRestFilter.java:120)
at com.company.rd.servlet.JspAuthorizationRestFilter.doFilter(JspAuthorizationRestFilter.java:84)
I have debugged the code and found entityManagerFactory for persistenceUnit "codeAuthorization" is not initialized. Only "org.jbpm.persistence.jpa.local" is available (verified through eclipse debugger) inside this method.
Note: This JAR is working fine in some other application where web application and JAR using same way to initialize entityMangerFactory [through Persistence.createEntityManagerFactory("")].
Please let me know How can I get "codeAuthorization" entiryManagerFactory
You are using Spring then use Spring, currently you are doing a lot of work to work around Spring and dependency injection and managed transaction. Don't use Persistence.createEntityManagerFactory(""). Just inject the EntityManager where you need it using an EntityManager field annotated with #PersistenceContext and specify the name of the one you want.
Also don't manage the transactions, entity manager yourself, spring does that for you. For this use the right PlatformTransactionManager the JpaTransactionManager and not the DatasourceTransactionManager as that won't work in a JPA environment. (At least not to manage your JPA transactions).
Doing this will really simplify your code and your life.
So basically ditch the service that is doing those nasty things and simple do things like this in your dao.
#Repository
public class YourDao {
#PersistenceContext(name="codeAuthorization")
private EntityManager em;
#Transactional
public Object getSingleResult(final String queryString, final String key,
final NamedQueryParameter namedQueryParameter) {
final Query query = em.createQuery(queryString);
setQueryParameter(query, namedQueryParameter);
return query.getSingleResult();
}
}
In your configuration replace the DatasourceTransactionManager with the JpaTransactionManager and add <tx:annotation-driven />. Then clean your code.
Note: The JpaTransactionManager is perfectly capable of managing plain JDBC transactions if you still need those, ideally you would have a single transaction manager.

DbUnit H2 in memory db with Spring and Hibernate

Hi I'm trying a little POC with JPA and unit test to verify that the DB schema is created. I'm working with H2 DB and I set to Hibernate create the schema from the entities, but when DbUnit tries to initialize the DB from a dataset I always get a Table ... not found in tableMap. I read that I have to add the property DB_CLOSE_DELAY=-1 to DB URL but is like after Hibernate creates the schema the DB is losted when DbUnit tries to initialize.
Any ideas? Any help is highly appreciated.
This is my config:
application-context.xml
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSourceH2" />
<property name="packagesToScan" value="com.xxx.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
<!-- property name="databasePlatform" value="org.hibernate.dialect.MySQLInnoDBDialect" /-->
<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
<!-- property name="database" value="MYSQL" /-->
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="javax.persistence.validation.mode">CALLBACK</prop>
</props>
</property>
</bean>
<bean id="dataSourceH2"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
RepositoryTest.java
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "/application-context-test.xml" })
#Transactional
public class SystemEntityRepositoryH2Test {
#Inject
private SystemEntityRepository repository;
#Inject
private DataSource dataSourceH2;
private IDatabaseConnection connection;
#Before
public void setUp() throws Exception {
IDatabaseConnection dbUnitCon = null;
dbUnitCon = new DatabaseDataSourceConnection(dataSourceH2, "testdb");
dbUnitCon.getConfig().setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
IDataSet dataSet = this.getDataSet("dataset-systementity.xml");
DatabaseOperation.INSERT.execute(dbUnitCon, dataSet);
}
#After
public void tearDown() throws Exception {
//DatabaseOperation.DELETE_ALL.execute(this.getConnection(), this.getDataSet(dataSetFile));
}
#Test
public void test() throws Exception {
}
protected IDataSet getDataSet(String dataSetFile) throws Exception {
ResourceLoader resourceLoader = new ClassRelativeResourceLoader(this.getClass());
Resource resource = resourceLoader.getResource(dataSetFile);
if (resource.exists()) {
return new FlatXmlDataSetBuilder().build(resource.getInputStream());
}
return null;
}
}
dataset-systementity.xml
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<System_Entities id="2" name="NAME" phone01="+52-55-55555555" email="a#a.com"
address01="Street" address02="123" address03="1" address04="Address04"
address05="Address05" city="City" state="State" country="MX"
zipcode="12345" />
</dataset>
Error
ERROR DatabaseDataSet:286 - Table 'System_Entities' not found in tableMap=org.dbunit.dataset.OrderedTableNameMap[_tableNames=[], _tableMap={}, _caseSensitiveTableNames=false]
I can see that the tables are created by hibernate because the log shows all the sql sentences without error.
Thanks.
SOLUTION
Thanks Mark Robinson
I modified the setUp method to:
#Before
public void setUp() throws Exception {
IDatabaseConnection dbUnitCon = null;
EntityManager entityManager = entityManagerFactory.createEntityManager();
Session session = entityManager.unwrap(Session.class);
SessionImplementor si = (SessionImplementor) session;
Connection conn = si.getJdbcConnectionAccess().obtainConnection();
dbUnitCon = new DatabaseConnection(conn);
//dbUnitCon.getConfig().setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
IDataSet dataSet = this.getDataSet("dataset-systementity.xml");
DatabaseOperation.INSERT.execute(dbUnitCon, dataSet);
}
It works now, what I don't understand yet is if I use HSQLDB I don't have this problem.
The problem is that DBUnit is loading the table data before Hibernate can initialize.
As part of your #setup, you'll need to get the Hibernate session. This should cause Hibernate to create your table. You could even force it by executing a simple query like select 1

Resources