#Autowired entityManagerFactory is null - spring

My app can't autowire entityManagerFactory.
My applicationContext.xml:
<tx:annotation-driven/>
<context:component-scan base-package="top.level.package" />
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocation">
<value>classpath:jpa-persistence.xml</value>
</property>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
My java class:
#Component
public class Engine {
#Autowired
#Qualifier("entityManagerFactory")
private EntityManagerFactory entityManagerFactory;
......
}
Question:
Why entityManagerFactory is null?

For spring to do autowring using annotations you have to tell spring that. In your xml configuration (assuming you don't already have context:component-scan element) add a context:annotation-config. This will instruct the spring application context to scan for annotations (like #Autowired, #Inject, #Resource etc.) to do autowiring.
Also make sure that the class you want the EntityManagerFactory to be injected into (the Engine class) is a spring managed bean. Spring will only inject references into spring managed beans.

Have you tried with this ?
private EntityManagerFactory entityManagerFactory;
#Autowired
#PersistenceUnit(unitName = "myUnitName")
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
I had the same error some time ago, and I found this a solution.

If you craeate your Engine with new Engine() (as stated in one of your comments), it's not managed by Spring. #Component has no effect then and dependencies won't be injected. You need to inject your engine.

Related

How to replace Spring ApplicationContext in Spring Boot

In an old spring application, I have the following in the applicationContext.xml file, now I need to rewrite it in Spring Boot?
How do I do that in Spring Boot?
Any help or hint would be greatly appreciated it?
Spring applicationContext.xml
<bean id="dealTicketDAO" class="SqlMapDealTicketDAO">
<property name="dealTicketMapper" ref="dealTicketMapper" />
</bean>
<bean id="dealTicketMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="DealTicketMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="dealTicketService" parent="baseTransactionProxy">
<property name="target">
<bean class="DealTicketServiceImpl">
<property name="dealTicketDAO">
<ref local="dealTicketDAO"/>
</property>
</bean>
</property>
</bean>
Create a class annotated with #Configuration
the dependency is (org.springframework.context.annotation.Configuration)
and for each bean declaration in your XML file create a #Bean (org.springframework.context.annotation.Bean) method within this class.
#Configuration
public class MyConfiguration {
#Bean
public MapperFactoryBean<DealTicketMapper> dealTicketMapper() throws Exception {
MapperFactoryBean<DealTicketMapper> factoryBean = new MapperFactoryBean<>(DealTicketMapper.class);
factoryBean.setSqlSessionFactory(sqlSessionFactory());
return factoryBean;
}
#Bean
public DealTicketService dealTicketService(DealTicketDAO dealTicketDAO){
return new DealTicketServiceImpl(dealTicketDAO);
}
this should surely help you

Null pointer in Initialising NamedParameterJdbcTemplate bean

If i do the code in controller with
final DataSource dataSource = (DataSource) getApplicationContext().getBean("dataSource", DataSource.class);
final JdbcTemplate jdbcTemplate = new JdbcTemplate(jdbcDataSource);
final NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
This will work fine
If i have to attain the same in Spring application context
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" autowire="constructor" />
<bean class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"
id="namedParameterJdbcTemplate">
<constructor-arg ref="jdbcTemplate" />
</bean>
In Hibernate Repository Class
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
This throws error
Is there any way to make the object namedParameterJdbcTemplate working in Repository class
If you've declared your jdbcTemplate in your XML, that is all you should need.
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
You do need to set the datasource on the JdbcTemplate though.
Once you autowire the JdbcTemplate into your DAO, you should be able to use that to create a NamedParameterJdbcTemplate.
#Repository
public class DAOImpl implements DAO {
#Autowired
private JdbcTemplate jdbcTemplate;
public void foo() {
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
....
}
}
You need to actually create an instance of it before you use it.
If you want to use XML to create your instance you can do that too, but you'll need to autowire in the instance that gets created by the XML.
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="namedParamterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="jdbcTemplate"/>
</bean>
Then you should only have to autowire in the NamedParameterJdbcTemplate into your DAO.

TransactionRequiredException on Delete Query Execution

I have a strange behaviour happening when executing a delete query. I use spring mvc 3.1 with JPA (hibernate) and oracle DB.
Below is the relevant part of my applicationcontext
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
</bean>
I have created a custom annotation
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Transactional(isolation = Isolation.DEFAULT, propagation=Propagation.REQUIRED)
public #interface DefaultServiceTransaction{}
which I use on the services to make them transactional.
#Service
#DefaultServiceTransaction
public class UserServiceImpl implements UserService {
#Autowired UserRepositoryuserRepository;
#DefaultServiceTransaction
public void deleteAllForUser(User user){
userRepository.deleteAllForUser(user);
}}
The problem is when I execute this service method, I get the exception
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:321)
at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:15)
The same strategy works for me when I use it for other services (in the same package in fact) - so I don't think the problem has anything to do with the configuration.
I am clueless....

Getting an EhCache instance with Spring... intelligently

I need to get a specific EhCache instance by name and I'd prefer to autowire if possible. Given the following automatically configured controller, how can I autowire in the cache instance I'm looking for?
#Controller
public class MyUniqueService {
...
}
<beans ...>
<ctx:component-scan base-package="my.controllers"/>
<mvc:annotation-driven />
</beans>
How do I configure EhCache in my application context? I don't see any log messages from EhCache about it loading the ehcache.xml file in my /WEB-INF/ directory. How do I make it load it?
How can I integrate EhCache with my Spring application to have it load the ehcache.xml file from my /WEB-INF/ directory and autowire a cache by a given name into my MyUniqueService controller?
First you need to create a Ehcache CacheManager singleton in you app context like this:
<bean id="myEhCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:my-ehcache.xml"/>
</bean>
Here configLocation is set to load from classpath or use value="/WEB-INF/my-ehcache.xml".
In your controller simply inject the CacheManager instance:
#Controller
public class MyUniqueService {
#Resource(name="myEhCacheManager")
private CacheManager cacheManager;
...
}
Alternatively, if you'd like to go the "entirely autowired" route, do:
<bean class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="/WEB-INF/ehcache.xml"/>
</bean>
</property>
</bean>
Setup your class like so:
#Controller
public class MyUniqueService {
#Autowired
private org.springframework.cache.CacheManager cacheManager;
public org.springframework.cache.Cache getUniqueObjectCache() {
return cacheManager.getCache("uniqueObjectCache");
}
}
uniqueObjectCache corresponds to this cache instance in your ehcache.xml cache definition:
<cache name="uniqueObjectCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LRU"
transactionalMode="off"/>
There isn't a way to inject an actual cache instance, but as shown above, you can inject a cache manager and use it to get the cache you're interested in.
Assuming you have cacheManager defined:
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:/ehcache.xml"/>
</bean>
You can get/inject specific cache like this:
#Value("#{cacheManager.getCache('myCacheName')}")
private Cache myCache;
See also examples how to use Spring EL inside the #Value() http://www.mkyong.com/spring3/spring-el-method-invocation-example/ if you are interested.
You can also use autowire if the context can find a bean with the correct class. Here is how I configured my xml
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation">
<value>WEB-INF/ehcache.xml</value>
</property>
</bean>
<bean id="cache" class="net.sf.ehcache.Cache" factory-bean="cacheManager" factory-method="getCache">
<constructor-arg value="CacheNameHere" />
</bean>
And my java class
#Autowired
private net.sf.ehcache.Cache cache;
This setup works for me.
Indeed! Or if you want to use a java config class:
#Inject
private ResourceLoader resourceLoader;
#Bean
public CacheManager cacheManager() {
EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
try {
ehCacheCacheManager.setCacheManager(ehcacheCacheManager().getObject());
} catch (Exception e) {
throw new IllegalStateException("Failed to create an EhCacheManagerFactoryBean", e);
}
return ehCacheCacheManager;
}
#Bean
public FactoryBean<net.sf.ehcache.CacheManager> ehcacheCacheManager() {
EhCacheManagerFactoryBean bean = new EhCacheManagerFactoryBean();
bean.setConfigLocation(resourceLoader.getResource("classpath:ehcache.xml"));
return bean;
}

Spring #PersistenceContext how to inject manually the entity manager in my GenericDao

Hallo all:
I read the spring reference about this point.
I would choose to use the #PersistenceContext in my DAO to inject a shared transactional entity manager, but since I use the GenericDaoJpaImpl pattern over two entityManagerFactories that point to 2 different persistence units I cannot use it.
So right now in my application I have this configuration:
entityManagerFactoryies:
<bean id="entityManagerFactoryIban0" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/contratto-persistence-iban0.xml" />
</bean>
<bean id="entityManagerFactoryCont0" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/contratto-persistence-cont0.xml" />
</bean>
<bean abstract="true" id="abstractDaoJpaImplIban0" lazy-init="false">
<property name="entityManagerFactory" ref="entityManagerFactoryIban0" />
</bean>
<bean abstract="true" id="abstractDaoJpaImplCont0" lazy-init="false">
<property name="entityManagerFactory" ref="entityManagerFactoryCont0" />
</bean>
Then each of my DAOs is an instance of the GenericDaoImpl:
#Repository
public class GenericDaoJpaImpl<T, ID extends Serializable> implements GenericDao<T, ID> {
private Class<T> entityClass;
private EntityManagerFactory entityManagerFactory;
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
public GenericDaoJpaImpl() {
super();
}
public GenericDaoJpaImpl(Class<T> entityClass) {
super();
this.entityClass = entityClass;
}
/**
* #see it.alten.intesasanpaolo.contratto.dao.common.GenericDao#getItemByID(java.io.Serializable)
*/
#Override
public T getItemByID(ID id) {
EntityManager em = entityManagerFactory.createEntityManager();
return em.find(entityClass, id);
}
I construct my dao via spring in this way:
<bean id="eventMessageDao" parent="abstractDaoJpaImplCont0" class="it.alten.intesasanpaolo.contratto.dao.common.GenericDaoJpaImpl">
<constructor-arg>
<value>it.alten.intesasanpaolo.contratto.domain.event.OnlineEventMessage</value>
</constructor-arg>
</bean>
Now I would like to modify the GenericDaoJpaImpl as described in the spring documentation not to be associated to the entityManagerFactory from which I have to create every time the entityManager but directly to the entityManager.
I would like to define it in the context in a way I can inject it to the correct abstract dao to be extended from every dao.
<bean abstract="true" id="abstractDaoJpaImplIban0" lazy-init="false">
<property name="entityManagerFactory" ref="entityManagerFactoryIban0" />
</bean>
How can I achieve this?
kind regards
Massimo
You can use SharedEntityManagerBean to construct a transactional EntityManager from the EntityManagerFactory:
<bean id="entityManagerFactoryIban0"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
</bean>
<bean id="entityManagerIban0"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactoryIban0" />
</bean>
<bean abstract="true" id="abstractDaoJpaImplIban0" lazy-init="false">
<property name="entityManager" ref="entityManagerIban0" />
</bean>
You can provide the persistence unit name in the xml configuration, using the SharedEntityManagerBean, like below:
<bean id="testDao" class="com.test.persistence.dao.BaseDAO">
<property name="entityManager">
<bean class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="persistenceUnitName" value="persistence-test-unit" />
</bean>
</property>
</bean>
of course, you can have the SharedEntityManagerBean as a separate bean
Here, I m injecting entityManager into BaseDAO as you're doing using #PersistenceContext(unitName="...")

Resources