SessionFactory is null - spring

I'm using Spring with Hibernate and originally set up my project with a hibernate xml config, which resulted in performance issues and seemed like it was the wrong way to do it. I'm now trying to inject my SessionFactory, starting with 1 dao, but get a null pointer exception where sessionFactory.getCurrentSession() is called. I think my code looks like the examples I've seen. I'm stumped. I also tried not using resource and injecting the sessionFactory into the dao in the application context instead. Same result.
ApplicationContext.xml
<context:component-scan base-package="path.to.base">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingDirectoryLocations">
<list>
<value>classpath*:/path/to/mapping/files</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
myDAO
#Repository
public class myDAO {
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory(){
return sessionFactory;
}
#Resource(name="sessionFactory")
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public myDAO() {
}
#SuppressWarnings("unchecked")
#Transactional(readOnly=true)
public List<Things> getAllThings() {
return sessionFactory.getCurrentSession().createCriteria(EvalMasterEvaluationType.class)
.add(Restrictions.eq("active", "Y")).addOrder(Order.desc("createDtTm")).list();
}
}
Spring 3.2.1, Hibernate 3.6.10

I got it working, though I'm not sure which modification solved the problem. SRT_KP might be right after all about the datasource since I added some properties to it (maxactive, maxidle, validationquery). I switched to LocalSessionFactoryBean since I'm using xml mappings and added the mapping file suffix to the mappingLocations property. I also moved #Transactional to the service layer where it belongs.
Here's what I ended up with:
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:property-placeholder location="classpath*:WEB-INF/*.properties"/>
<context:component-scan base-package="org.base.to.scan">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="oraDataSource" />
<property name="mappingLocations" value="classpath*:org/path/to/mapping/files/*.hbm.xml" />
</bean>
<bean id="oraDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
<property name="validationQuery" value="SELECT 'x' FROM dual" />
</bean>
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
BTW great tutorial: http://www.byteslounge.com/tutorials/spring-with-hibernate-persistence-and-transactions-example

Related

Hazelcast client spring configuration

I have createed a Hazelcast manager which uses spring, hibernate, jpa. I can start my hazelcast instance.
The problem I have is I dont know how to configure a hazelcast client using spring config. I want to use in some other server component a hazelcast-client
I really have no idea how to start
any help would be appreciated
Below is my spring config for hazelcast server
Johan
<?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:hz="http://www.hazelcast.com/schema/spring"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.hazelcast.com/schema/spring
http://www.hazelcast.com/schema/spring/hazelcast-spring.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:${ecs.config.path}/ecs.properties</value>
<value>classpath*:config/ecs.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="ignoreResourceNotFound" value="true" />
</bean>
<context:component-scan base-package="nl.ict.psa.ecs.hazelcast.dao,nl.ict.psa.ecs.hazelcast.mapstores,nl.ict.psa.ecs.hazelcast.service" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${datasource.driverClassName}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}"/>
<property name="password" value="${datasource.password}"/>
</bean>
<bean id="hazelcast" class="com.hazelcast.core.Hazelcast"/>
<bean id="entityManagerFactoryBean"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="PU" />
<property name="packagesToScan">
<list>
<value>nl.ict.psa.hazelcast.model.ecs</value>
<value>nl.ict.psa.hazelcast.model.ecs.ocr</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.archive.autodetection">class</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryBean" />
</bean>
<bean id="transpInfo" class="nl.ict.psa.ecs.hazelcast.mapstores.TranspInfoMapStore"/>
<hz:hazelcast id="instance">
<hz:config>
<hz:network port="5701" port-auto-increment="true">
<hz:join>
<hz:multicast enabled="false"/>
</hz:join>
</hz:network>
<hz:map name="transp" read-backup-data="true">
<hz:map-store enabled="true" write-delay-seconds="60"
initial-mode="LAZY"
implementation="transpInfo"/>
</hz:map>
</hz:config>
</hz:hazelcast>
</beans>
Configured Multiple Ip's Using Pragmatically.
#Bean
public ClientConfig clientConfig() {
ClientConfig clientConfig = new ClientConfig();
ClientNetworkConfig networkConfig = clientConfig.getNetworkConfig();
networkConfig.addAddress("172.17.0.4:5701", "172.17.0.6:5701")
.setSmartRouting(true)
.addOutboundPortDefinition("34700-34710")
.setRedoOperation(true)
.setConnectionTimeout(5000)
.setConnectionAttemptLimit(5);
return clientConfig;
}
#Bean
public HazelcastInstance hazelcastInstance(ClientConfig clientConfig) {
return HazelcastClient.newHazelcastClient(clientConfig);
}
I would suggest to must read. http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#configuring-client-connection-strategy
Something like this (from https://github.com/neilstevenson/spring-boot-autoconfigure-test/tree/master/hazelcast-imdg-client)
#Configuration
#ConditionalOnMissingBean(ClientConfig.class)
static class HazelcastClientConfigConfiguration {
#Bean
public ClientConfig clientConfig() throws Exception {
return new XmlClientConfigBuilder().build();
}
}
#Configuration
#ConditionalOnMissingBean(HazelcastInstance.class)
static class HazelcastClientConfiguration {
#Bean
public HazelcastInstance hazelcastInstance(ClientConfig clientConfig) {
return HazelcastClient.newHazelcastClient(clientConfig);
}
}
Try to avoid XML, Spring is moving away from it.

Spring/Hibernate JPA NamedQuery not found

I have a weird issue: entity manager can't create named query, I'm getting java.lang.IllegalArgumentException: Named query not found while methods, like find() and merge(), works. createQuery() also works. I'm using Hibernate as JPA provider and Spring as DI container. Code and configs are follows:
spring-beans.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:component-scan base-package="org.example.testapp.database" />
<bean id="newsForm" class="org.example.testapp.presentation.form.NewsForm">
<property name="newsMessage" ref="news" />
<property name="newsList">
<list>
<ref bean="news" />
</list>
</property>
</bean>
<bean name="news" class="org.example.testapp.model.News">
</bean>
<bean name="/news" class="org.example.testapp.presentation.action.NewsAction"
scope="prototype">
<property name="dao" ref="dao" />
</bean>
<bean id="dao" class="org.example.testapp.database.dao.JpaHibernateNewsDao"
scope="singleton">
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.example.testapp.model"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
</bean>
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="login" />
<property name="password" value="password" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:annotation-config/>
<tx:annotation-driven transaction-manager="transactionManager" />
news.java
#Entity
#NamedQueries({
#NamedQuery(name="News.select", query="select n from News n order by news_date" ),
#NamedQuery(name="News.delete", query="delete from News where id in :value_list")
})
#Table(name="news")
public class News {
jpadao.java
public class JpaHibernateNewsDao implements Dao {
#PersistenceContext
private EntityManager entityManager;
#SuppressWarnings("unchecked")
#Override
#Transactional
public List<News> getList() throws DaoException {
List<News> news = entityManager.createNamedQuery("News.select").getResultList();
return news;
}
Found a answer: Spring just didn't see #Entity, so there was really no such #NamedQuery. Now I have to figure, why this config didn't work:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.example.testapp.model"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />

test and applicationContext

i use latest release of spring, spring data, jpa, hibernate and h2.
i try to run test (only repository test).
but i get this error: Failed to load ApplicationContext
my test class
#RunWith(SpringJUnit4ClassRunner.class)
#TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
#Transactional
#ContextConfiguration(
locations = {"classpath:applicationContext-test.xml"})
public class UserDaoTest extends AbstractTransactionalJUnit4SpringContextTests {
...
}
my applicationContext-test.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<context:property-placeholder location="classpath:/jdbc.properties"/>
<context:component-scan base-package="com.test.*" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<jpa:repositories base-package="com.test.va.repository"/>
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="idleConnectionTestPeriodInMinutes" value="${jdbc.idleConnectionTestPeriodInMinutes}"/>
<property name="idleMaxAgeInSeconds" value="${jdbc.idleMaxAgeInSeconds}"/>
<property name="maxConnectionsPerPartition" value="${jdbc.maxConnectionsPerPartition}"/>
<property name="minConnectionsPerPartition" value="${jdbc.minConnectionsPerPartition}"/>
<property name="partitionCount" value="${jdbc.partitionCount}"/>
<property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>
<property name="statementsCacheSize" value="${jdbc.statementsCacheSize}"/>
<property name="releaseHelperThreads" value="${jdbc.releaseHelperThreads}"/>
</bean>
so it's a config error.

Inject common attribute from spring configuration file to every test class

I have small clarification regarding the spring injection. I'm writing the test for services. Every Test class has a common attribute called "tenantId". Can I inject that attribute through spring configuration file.I don't want to add every test class to the spring configuration file, Is there a way to that?
#ContextConfiguration(locations = {"classpath*:applicationContext-service-test.xml"})
public class ApplicationServiceTest extends AbstractTestNGSpringContextTests {
#Autowired
TenantBasedSessionFactory tenantBasedSessionFactory;
#Autowired
private ApplicationService applicationService;
private String tenantId = "tenantId"; // I want this to inject from applicationContext-service-test.xml
private Session session;
}
Spring configuration file.
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- Use #Transaction annotations for managing transactions -->
<tx:annotation-driven/>
<!-- Activates scanning of #Autowired -->
<context:annotation-config/>
<!-- Activates scanning of #Service and #Repository -->
<context:component-scan base-package="lk.gov.elg"/>
<!-- JDBC property file -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<!--<value>classpath:test.jdbc.properties</value>-->
<value>jdbc.properties</value>
</list>
</property>
</bean>
<!--<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"-->
<!--p:driverClassName="org.hsqldb.jdbcDriver" p:url="jdbc:hsqldb:mem:test"-->
<!--p:username="sa" p:password="" />-->
<!-- create database connection pool -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<!--<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">-->
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="100"/>
<property name="maxWait" value="1000"/>
<property name="poolPreparedStatements" value="true"/>
<property name="defaultAutoCommit" value="true"/>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="lk.gov.elg.orm.model"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=${hibernate.dialect.test}
hibernate.hbm2ddl.auto=update
hibernate.cache.use_second_level_cache=true
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="tenantBasedSessionFactory" class="lk.gov.elg.orm.dao.impl.TenantBasedSessionFactoryImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
</beans>
Thank you in advance
Cheers
You can create a common superclass for all your tests to inject there your tenantId. With this, you will only have to inject only once and tenandId will be available to all your desired classes.

Struts2+Spring 3 validations issue

I am trying to use struts2 validations. I have a setup with Struts2.2.3 and Spring 3.0.5. I have a -validation.xml in place. Fields are getting validated and error message is getting displayed on the server console, but its not getting displayed on the UI. Also action is not getting forwarded to the results specified for the "input" tag.
My action class does not extend from ActionSupport instead it implements Preparable. Is this could be the problem?
So I also tried with my Action class define as
public class CandidateAction extends ActionSupport implements Preparable
on hitting the page i am getting following error
Invalid action class configuration that references an unknown class named [candidateAction]
even though i have a bean defined with name "candidateAction" in the application context.xml
ApplicationContext.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.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.0.xsd">
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="dao" class="org.kovid.dao.impl.DaoImpl" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/xyz" />
<property name="username" value="abc" />
<property name="password" value="abc" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="baseAction" scope="prototype" class="org.kovid.action.BaseAction">
</bean>
<bean id="candidateAction" scope="prototype"
class="org.kovid.matrimony.action.CandidateAction">
<constructor-arg ref="dao" />
</bean>
<bean id="simpleSearchAction" scope="prototype"
class="org.kovid.matrimony.action.SimpleSearchAction">
<constructor-arg ref="dao" />
</bean>
<bean id="advanceSearchAction" scope="prototype"
class="org.kovid.matrimony.action.AdvanceSearchAction">
<constructor-arg ref="dao" />
</bean>
<bean id="imageAction" scope="prototype"
class="org.kovid.matrimony.action.ImageAction">
<constructor-arg ref="dao" />
</bean>
</beans>

Resources