JPA tests hang while obtaining HSQL connection from Maven Command Line - spring

Tests work individually within Eclipse (right click, run as Junit), but when I run them from the command line with maven, it stops while trying to obtain a DataSource connection to the HSQL database.
LogicalConnectionImpl [DEBUG] Obtaining JDBC connection
The oddest part to me is that if I limit the tests being run to 10 (not classes, but individual #Test methods), it will work. But once that 11th test is run it bombs out. The test combinations do not matter, so if I have 30 tests, and I choose 11 or more to run, then it will fail. This made me think it is a DataSource connection max issue, but so far no luck with details of that. I have tried adding heap size just for giggles, but that did not work.
So prior to this hang, I have multiple successful JDBC connection and releases.
Here is my applicationContext-HSQL.xml, which is used for both the in Eclipse and Command Line versions. I know b/c I have forced each of them to fail by messing with the Class values below.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.company"/>
<import resource="classpath*:/application-context-cxf.xml"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceXmlLocation" value="META-INF/persistence.xml" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
</bean>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:test" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" >
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
All of my Test classes utilize Spring 3.2.5, JPA, DBUnit and extend AbstractInMemoryTests.java
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"classpath:applicationContext-hsqldb.xml"})
public class AbstractInMemoryTests {
private static final String FLAT_XML_DATASET = "FlatXmlDataSet.xml";
#Autowired
BasicDataSource bds;
#Before
public void setUp() throws Exception {
DatabaseOperation.CLEAN_INSERT.execute(getConnection(), getDataSet());
}
#SuppressWarnings("deprecation")
private IDataSet getDataSet() throws Exception {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(FLAT_XML_DATASET);
IDataSet dataset = new FlatXmlDataSet(inputStream);
return dataset;
}
private IDatabaseConnection getConnection() throws Exception {
Connection jdbcConnection = bds.getConnection();
IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);
return connection;
}
}
Any ideas on why I may be hanging on that connection, or an idea of how to troubleshoot?
Thanks,
Sean

Per the usual protocol, a good nights sleep helps you think. I completely over-looked the maxActive setting available for the appContext-hsqldb.xml property for my DataSource
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:test" />
<property name="username" value="sa" />
<property name="password" value="" />
****<property name="maxActive" value="-1"/>****
</bean>
Hope this helps someone else in the future.
http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html

if something is hanging you can use "kill -3 {process_number}" on Unix and it gives a thread dump (if not on Unix there is an equivalent on Windows/Mac). That will show where the lock problem is, which may give you an idea what causes it and how to fix it

If the hanging comes after few page access, (maybe 8 which is the default maxTotal), you are not never closing the connection and opening in every request.
Just use entityManager.close(); after the db queries or check if the a connection already exists before creating a new one.
The accepted answer is setting the maxTotal connections to unlimited. Connections will just keep pilling up.

Related

#PostConstruct not called (Primefaces & Spring & Hibernate)

I'm using Hibernate, Spring and Primefaces (and Maven) and I'm trying to run
#PostConstruct
init() {}
to initialize a location list inside a bean. But the init() method is never called. The projects structure is:
com.xxx
com.xxx.hibernate.dao
com.xxx.hibernate.dao.impl
com.xxx.hibernate.data
com.xxx.prime.faces.bean
com.xxx.spring.service
com.xxx.spring.service.impl
application context:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:property-placeholder location="classpath*:META-INF/*.properties"/>
<!-- Scan for all of Spring components such as Spring Service -->
<context:component-scan base-package="com.xxx"></context:component-scan>
<!-- Create Data Source bean -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://host:3306/db" />
<property name="username" value="user" />
<property name="password" value="password" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property value="persistenceUnit" name="persistenceUnitName" />
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Detect #Transactional Annotation -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
The LocationView Bean:
#ManagedBean
#ViewScoped
public class LocationView implements Serializable{
private static final long serialVersionUID = 1L;
#ManagedProperty("#{locationService}")
private LocationService locationService;
private Location location = new Location();
private List<Location> locations = new ArrayList<Location>();
#PostConstruct
public void init() {
this.locations = locationService.getAllLocations();
}
I run this on Glassfish4 in debug mode and the init() Method is never called. but I don't no why. It should be scanned for spring annotations, but I don't know how I could be sure about that.
Also I'm not sure what
<context:property-placeholder location="classpath*:META-INF/*.properties"/>
does.
Any ideas what I could check?

database not updated using JPA and spring when new entries are made

I am configuring a simple JPA application using Spring framework.
My goal is to populate the db with data during JUnit Test runs. I understand this is not ideal. But I want it for different purposes.
Here is my persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0">
<persistence-unit name="tothought-tutorial-test" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<!-- <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" /> -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
test-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.2.xsd">
<!-- Database -->
<!-- <jdbc:embedded-database id="datasource" type="H2"></jdbc:embedded-database> -->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/to_thought_tutorial" />
<property name="username" value="demo" />
<property name="password" value="demo" />
</bean>
<!-- Entity Manager -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="persistenceUnitName" value="tothought-tutorial-test" />
</bean>
<!-- Transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Jpa Repositories -->
<jpa:repositories base-package="com.cloudfoundry.tothought.repositories"></jpa:repositories>
</beans>
Here is junitTest class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations="classpath:META-INF/test-context.xml")
#Transactional
public class PostPartRepositoryTest {
#Autowired
PostPartRepository repository;
#Test
public void test() {
PostPart postPart = new PostPart();
String body = "Hello";
postPart.setBody(body);
repository.save(postPart);
PostPart dbPostPart = repository.findOne(postPart.getPostPartId());
assertNotNull(dbPostPart);
assertEquals(body, dbPostPart.getBody());
}
#Test
public void insertTest(){
Post post = new Post();
post.setPostDate(new Date());
post.setTitle("First Post");
PostPart postPart = new PostPart();
String body = "Hello";
postPart.setBody(body);
postPart.setPost(post);
repository.save(postPart);
PostPart dbPostPart = repository.findOne(postPart.getPostPartId());
assertNotNull(dbPostPart);
assertNotNull(dbPostPart.getPost());
assertEquals(body, dbPostPart.getBody());
}
}
Both the test passes. But I do not see any entry in tables, although tables are created the first time.
You won't see any entries because you are running the test with #Transactional using the SpringJUnit4ClassRunner. The default for running tests with #Transactional is for any database changes to be automatically rolled back once the test is finished. For more information see this question here
The order in which these things happen is as follows:
Test starts, setup scripts are run, which creates your tables.
Tests start running in transactional context.
Tests finish running, and any database changes made during your test, are automatically rolled back, leaving the database in the state it was in before the tests ran.
You can change this default behaviour you can use #TransactionConfiguration(defaultRollback=false) at the top of the class. However this is bad practice because unit tests should not depend on each other and shouldn't be permanently modifying application state. Also, if you are depending on one test to set something in the environment and use it in the next test, there is no guarantee which order the tests are executed by test runner.

Spring jdbc transaction not commit

I have following Spring configuration:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" >
Beans with database and transaction management are configured as below:
<bean id="sufe.ncm.docDao" class="DocDaoImpl" scope="singleton">
<property name="jdbcTemplate" ref="sufe.ncm.jdbcTemplate"/>
</bean>
<bean id="sufe.ncm.jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="sufe.ncm.filterDB"/>
<property name="fetchSize" value="5000"/>
</bean>
<bean id="sufe.ncm.filterDB" class="org.apache.commons.dbcp.BasicDataSource">
<property name="defaultAutoCommit" value="false" />
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="..."/>
<property name="username" value="..."/>
<property name="password" value="..."/>
<property name="initialSize" value="1"/>
<property name="minIdle" value="1"/>
<property name="maxIdle" value="5"/>
<property name="maxOpenPreparedStatements" value="5"/>
</bean>
<context:annotation-config/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="sufe.ncm.filterDB"></property>
</bean>
DocDaoImpl class implements method updateData from interface DocDao:
#Transactional(rollbackFor = SQLException.class, propagation = Propagation.REQUIRES_NEW)
public synchronized void updateData() {
jdbcTemplate.batchUpdate(UPDATE_QUERY_1);
jdbcTemplate.batchUpdate(UPDATE_QUERY_1);
}
Because dataSource has set autocommit option on false, I expect that transaction will be committed only when both batchUpdates operation will finish whithout error. Unfortunatelly, unless both updates finishes whithout error, commit is not performed and I don't see any changes in database. Whats wrong ? Why #Transactional annotation doesn't work and commit is not performed ?

How to connect to multiple database using spring hibernate entitymanager

I have two databases for two different organizations with same database tables and objects. Now the application need to support both DB. Each user is attached to one organization and based on his login id application need to connect to particular DB and perform same operations.
So all Spring beans remain the same except target Database. How to do that most efficient way. I can think of creating multiple EntityManagerFactory in spring applicationContext file and in DAO I can select particular entitymanager based on user id/name (by passing it as an argument etc)
But what will be most efficient/correct way if we consider second level caching etc.
?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation=
"http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.2.xsd">
<tx:annotation-driven />
<bean id="empSvc" class="com.techcielo.sampleproject.service.EmployeeService">
<property name="empDao" ref="empDao"></property>
</bean>
<bean id="empDao" class="com.techcielo.sampleproject.dao.EmployeeDAO">
<property name="fac" ref="entityManagerFactory"></property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="config/persistence.xml"></property>
<property name="dataSource" ref="dataSource_2" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<!-- Create one more entitymanager factory here with _2 and rename previous one with _1 -->
<bean id="dataSource_1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/northwind" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="dataSource_2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/northwind_dup" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
</beans>
Thanks in advance.

NullPointerException from DAO by using crudRepositoy

i got java.lang.NullPointerException by using CrudRepository
my project looks like this:
strut2 action
service
repository
domain
class Action {
#Autowired MyService service;
public String execute(){
service.getList();
return "ok";
}
}
interface Service {
List getList();
}
#org.springframework.stereotype.Service
class ServiceImpl implements Service {
#Autowired MyRepository repo;
List getList(){
return (List)repo.findAll();
}
}
package com.mycompany.repositories;
interface MyRepository extends CrudRepository<MyPojo, String>{}
here is the config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="com.mycompany.repositories" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" >
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="unit-name" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="database" value="POSTGRESQL"/>
</bean>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="root" />
<property name="password" value="root" />
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://127.0.0.1:5432/mydb" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"></bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
I'm new here, and everytime i call the Action class, the service is injected, but MyRepository is alway null.
could someone help me with please, if you need more infos, pls let me know, thx!
EDIT 1
StackTrace:
2012-06-26 15:33:32,041 INFO - com.myproject.action.project.preparation.ApplicationAction - listing application...
java.lang.NullPointerException
at com.myproject.service.impl.ApmProjectPreparationServiceImpl.getAllApplications(ProjectPreparationServiceImpl.java:41)
at com.myproject.action.project.preparation.ApplicationAction.listAction(ApplicationAction.java:67)
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:601)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:453)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:292)
I also tried to debug it by myself. i found on the class ServiceImpl that the #Autowired MyRepository repo is null.
Seems i found the answer, thank #MartenDeinum from Spring Forum.
here are the tricks:
i am using struts2 for the GUI, so i need struts2 spring plugin to rewrite the struts2 object factory, so that the spring can find struts action.
i added this config for #Service
<context:component-scan base-package="com.myproject" />
basically i also need
<jpa:repositories base-package="com.myproject.repository" />
to find CrudRepository.
hope this can help others.

Resources