NullPointerException from DAO by using crudRepositoy - spring

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.

Related

single jpa transaction manager for multiple entitymanagers

#Repository
#Transactional
#Scope("prototype")
public class EntityManagerImpl implements EntityManagerGenerator {
#PersistenceContext(unitName = "test")
#Qualifier("transactionManager")
private EntityManager entityManager;
#PersistenceContext(unitName = "test1")
#Qualifier("transactionManager1")
private EntityManager entityManager2;
#Override
public EntityManager getEntityManager(String userType) {
if(userType.equals("test")){
return entityManager2;
}else{
return entityManager;
}
}
here how to use according entitymanager wise transaction manager dynamically.below i shared my xml configure 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:jee="http://www.springframework.org/schema/jee"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.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
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx">
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="false" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />
<bean id="entityManagerFactory2"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="test1.ds" />
<property name="persistenceUnitName" value="test1" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapterFC" />
<property name="persistenceXmlLocation" value="classpath:jpa-persistence.xml" />
</bean>
<bean id="jpaVendorAdapterFC"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="false" />
</bean>
<bean id="transactionManager1" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory2" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache" />
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" />
<!-- Transaction manager for a single JPA EntityManagerFactory (alternative
to JTA) -->
<!-- Activates various annotations to be detected in bean classes: Spring's
#Required and #Autowired, as well as JSR 250's #PostConstruct, #PreDestroy
and #Resource (if available) and JPA's #PersistenceContext and #PersistenceUnit
(if available). -->
<context:component-scan base-package="com.wmi.test" annotation-config="true"
scope-resolver="org.springframework.context.annotation.Jsr330ScopeMetadataResolver"/>
<!-- Instruct Spring to perform declarative transaction management automatically
on annotated classes. -->
<tx:annotation-driven />
<cache:annotation-driven />
so how can i use single transaction manager for multiple data source according to my configuration
and here we are used for transactional manager as #Transactional annotation

#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?

SessionFactory is null

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

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.

Resources