Spring 3.1 Missing ServletContext - spring

I am trying to write an integration test for my spring application. All my spring beans are defined in an xml file, so I am using profiles to parse them out.
Here is my test:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader = GenericXmlContextLoader.class, locations = {"classpath:/spring/spring-config.xml"})
#Profile("dev")
public class AccountDAOTest {
private EmbeddedDatabase database;
#Autowired
AccountDAO accountDAO;
#Before
public void setUp() {
System.setProperty("spring.profiles.active", "dev");
database = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).setName("memdb")
.addScript("classpath:resources/createAccount.sql").build();
Assert.assertNotNull(database);
}
#Test
public void testFind() throws Exception {
List<Account> accounts = accountDAO.findAll();
}
}
My spring-config.xml is just a standard configuration file
<beans>
<beans profile="prod" >
<context:annotation-config/>
<tx:annotation-driven transaction-manager="myTX" proxy-target-class="true"/>
<aop:aspectj-autoproxy/>
...
<beans profile="prod" >
<transaction managers, httprequests and such >
</beans>
<!-- end of production beans -->
<!-- the following are for local testing -->
<beans profile="dev" >
</beans>
<transaction managers and such >
<!-- end of local testing beans -->
</beans>
My spring version is 3.1.Release for spring-test, spring-transaction, spring.web.servlet, spring.web
As I am using servlet 2.5 I cannot use the newer Spring MVC configuration
When I try and run my test I get the following exception:
Caused by:
org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method [public org.springframework.web.servlet.HandlerMapping
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping()]
threw exception; nested exception is
java.lang.IllegalArgumentException: A ServletContext is required to
configure default servlet handling
Caused by: java.lang.IllegalArgumentException: A ServletContext is
required to configure default servlet handling
I can't figure out:
Why the servlet is required when I don't use it explicitly for tests
How to get the test servlet context loaded for xml without using spring mvc

Split the spring context config into root (non-web-related beans) and mvc (web-related beans) parts, or create a separate test config xml.

Related

Camel OSGI: how do I get the spring application context?

Below is a snippet from the camle-osgi example. I can obtain the camel context but how do I get the original spring application context? Or how am I supposed to get a reference to "mybean"?
MyRouteBuilder.java:
public class MyRouteBuilder extends RouteBuilder {
public static void main(String[] args) throws Exception{
new Main().run(args);
}
public void configure() {
// set up the transform bean
ModelCamelContext mc = getContext();//ok, I can get the camel context fine
//but how to get the spring context to get to "mybean"???
//set up routes
}
}
beans.xml:
<beans>
<camel:camelContext xmlns="http://camel.apache.org/schema/spring">
<package>org.apache.servicemix.examples.camel</package>
-----
</route>
</camel:camelContext>
<bean id="mybean" class="myclass"/>
</beans>
You should not use the spring context directly. Instead use the spring features to inject the beans you need.
Define the routebuilder as a bean in the spring context and use a setter and to inject myBean.
Keep the auto discovery and use annotations like #Autowired in the routebuilder to inject mybean.
A third option is to use getContext().getRegistry(). The registry allows to access all beans of the spring context by name or by type.
It would not be camel if we are already out of options :-)
So another options is to use the bean component of camel to access beans from the spring context: http://camel.apache.org/bean.html

jersey-spring3: Injecting Jersey OAuth resource into Spring managed Bean

I am trying to insert a Jersey 2.7 resource withing a Spring managed bean. Specifically, I want to inject OAuth1Signature within a Spring bean like so:
#Component
public class OAuthManager {
#Inject
private OAuth1Signature oAuthSignature;
private void someMethod() {
String signature = oAuthSignature.generate(oauthRequest, params, secrets);
}
}
I have tried using instructions provided within the HK2 Spring integration document: HK2 Spring Integration. Following the document, I added this to my spring xml configuration:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="hk2">
<bean class="org.jvnet.hk2.spring.bridge.api.SpringScopeImpl" >
<property name="ServiceLocatorName" value="HK2ToSpringTest" />
</bean>
</entry>
</map>
</property>
</bean>
<bean id="org.glassfish.jersey.oauth1.signature.OAuth1Signature"
class="org.glassfish.jersey.oauth1.signature.OAuth1Signature"
scope="hk2"
lazy-init="true" />
However, I keep getting this exception when I start my webapp:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.glassfish.hk2.api.ServiceLocator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:952)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:821)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:795)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
OAuth1Signature documentation states that the ServiceLocator is supposed to be injected by HK2 framework which Jersey 2.7 uses. I am very confused on how I can get Spring to instantiate OAuth1Signature for me using the jersey-spring3 bridge since it does not seem to know where the Service locator should come from.
I have tried searching through StackOverflow and other Jersey message boards, but most of them deal with the opposite use case (injecting spring beans in a Jersey resource). Any help on this would be greatly appreciated !
I have recently done the development for OAuth in my project where I used Jersey 2.9.1 with Spring.
Below is what needs to be done to autowire the "OAuth1Signature's" instance in the Spring as we require hk2 to spring bridge to inject the hk2 services in the spring.
1.Define the custom hk2 scope
#Bean
public static CustomScopeConfigurer scopeConfigurer() {
Map<String, Object> scopeMap = new HashMap<String, Object>();
SpringScopeImpl hk2SpringScope = new SpringScopeImpl();
CustomScopeConfigurer customScopeConfigurer = new CustomScopeConfigurer();
hk2SpringScope.setServiceLocatorName("hk2SpringLocator");
scopeMap.put("hk2", hk2SpringScope);
customScopeConfigurer.setScopes(scopeMap);
return customScopeConfigurer;
}
2.Define the OAuth1Signature bean in "hk2" scope
#Bean(name = "oauth1Signature")
#Scope("hk2")
public OAuth1Signature getOAuth1Signature() {
ServiceLocator hk2ServiceLocator = ServiceLocatorFactory.getInstance()
.find("hk2SpringLocator");
OAuth1Signature oAuth1Signature = new OAuth1Signature(hk2ServiceLocator);
return oAuth1Signature;
}
3.After you are done with above 2 steps, you are ready to the autowire the "OAuth1Signature".
#Autowired
private OAuth1Signature oAuth1Signature;
Cheers

Autowiring request scoped beans into application scoped beans

Is it possible to autowire a request scoped bean into an application scoped bean. i.e
I have a class RequestScopedBean:
class RequestScopedBean {
....
....
....
}
and a class Application scoped bean in which the request scoped bean is autowired.
class ApplicationScopedBean {
#Autowire
private RequestScopedBean requestScopedBean;
....
....
....
}
and the spring-config xml is as follows:
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
">
<bean id="applicationScopedBeans" class="ApplicationScopedBean" />
<bean id="requestScopedBean" class="RequestScopedBean" scope="request">
</bean>
</beans>
when I try to run this application the bean creation of applicationScopedBean fails with the following error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ApplicationScopedBean': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private RequestScopedBean requestScopedBean; nested exception is java.lang.IllegalStateException: No Scope registered for scope 'request'
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075)
at com.amazon.coral.reflect.instantiate.SpringInstantiatorFactory$1.newInstance(SpringInstantiatorFactory.java:168)
... 19 more
You have to mark your requestScopedBean as a scoped proxy also, this way Spring will inject in a proxy for requestScopedBean and in the background manage the scope appropriately.
<bean id="requestScopedBean" class="RequestScopedBean" scope="request">
<aop:scoped-proxy/>
</bean>
More here
The exception above suggests that you have not correctly configured Spring for the provision of request scoped beans.
You need to add this to your web.xml as described in the docs here:
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
However, there is more to your question than just configuration. You are attempting to inject a request scoped bean into a singleton scoped bean. Spring resolves dependencies and instantiates singletons when the DI container starts. This means that ApplicationScopedBean will only be created once (at this point there will be no request in flight and so the autowiring will most likely fail).
If you were using a prototype scoped bean instead of request scoped you'd have to consider a way of suppling the singleton scoped bean with a fresh instance everytime it was used. The approaches for this are described in the Method Injection chapter of the Spring docs.
#Airwavezx the annotation equivalent is the followinng:
#Scope( value = SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS )

Spring Data JPA, Spring 3.1.1, xml-less configuration, does not create repositories beans

Trying to use the Spring Data JPA to generate the DAO objects automatically using the <repositories /> with the base-package linking the package that contains the DAO interfaces like:
public interface UserDAO extends JpaRepository<User, String> {
}
but it fails wiring the DAO objects in the service beans, the exact error is:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ACLService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private pkg.service.UserServ pkg.service.ACLServ.userServ; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServ': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private pkg.repositories.UserDAO pkg.service.UserServ.userDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [pkg.repositories.UserDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at pkg.config.WebAppInit.onStartup(WebAppInit.java:35)
The application bootstrap start at WebAppInit.Java since it implements the WebApplicationInitializer interface, the web.xml code is:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"></web-app>
The WebAppInit.Java code the onStartup method as:
public class WebAppInit implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext context =
new AnnotationConfigWebApplicationContext();
context.register(ApplicationContextConfig.class);
context.refresh();
...
Then the ApplicationContextConfig class is annotated with #Configuration, code is:
#Configuration
#PropertySource("classpath:application.properties")
#ImportResource("classpath:*springDataConfig.xml")
#Import({BasicDataSourceConfig.class,PersistenceSpringDataJpaConfig.class})
#ComponentScan(basePackages={"pkg.service","pkg.utils"})
public class ApplicationContextConfig {
}
so this is only the main/entry point for the Java configuration, then it follow application.properties (Not included but just ask for it), then the springDataConfig.xml with code:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="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.xsd">
<repositories base-package="pkg.repositories" />
</beans:beans>
The BasicDataSourceConfig.Java configure the DataSource #Bean as:
#Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
...
The PersistenceSpringDataJpaConfig.Java configure the LocalContainerEntityManagerFactoryBean as:
#Configuration
public class PersistenceSpringDataJpaConfig {
...
#Autowired
DataSource dataSource;
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
...
The other files are not directly related, if I cut off the dependency removing/commenting the code:
#Autorire
private UserDAO userDAO
in the UserService class; the application runs without error, I mean besides the null pointer exception when accessing the dao object in the service bean.
So the question is: Why the Spring Data JPA does not create the userDAO bean?
PS: I did deliberately get rid from all #Transactions management to simplify it, besides it should work without transaction, isn't it?

Dependency Injection with Spring/Junit/JPA

I'm trying to create JUnit tests for my JPA DAO classes, using Spring 2.5.6 and JUnit 4.8.1.
My test case looks like this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"classpath:config/jpaDaoTestsConfig.xml"} )
public class MenuItem_Junit4_JPATest extends BaseJPATestCase {
private ApplicationContext context;
private InputStream dataInputStream;
private IDataSet dataSet;
#Resource
private IMenuItemDao menuItemDao;
#Test
public void testFindAll() throws Exception {
assertEquals(272, menuItemDao.findAll().size());
}
... Other test methods ommitted for brevity ...
}
I have the following in my jpaDaoTestsConfig.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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="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">
<!-- uses the persistence unit defined in the META-INF/persistence.xml JPA configuration file -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="CONOPS_PU" />
</bean>
<bean id="groupDao" class="mil.navy.ndms.conops.common.dao.impl.jpa.GroupDao" lazy-init="true" />
<bean id="permissionDao" class="mil.navy.ndms.conops.common.dao.impl.jpa.PermissionDao" lazy-init="true" />
<bean id="applicationUserDao" class="mil.navy.ndms.conops.common.dao.impl.jpa.ApplicationUserDao" lazy-init="true" />
<bean id="conopsUserDao" class="mil.navy.ndms.conops.common.dao.impl.jpa.ConopsUserDao" lazy-init="true" />
<bean id="menuItemDao" class="mil.navy.ndms.conops.common.dao.impl.jpa.MenuItemDao" lazy-init="true" />
<!-- enables interpretation of the #Required annotation to ensure that dependency injection actually occures -->
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<!-- enables interpretation of the #PersistenceUnit/#PersistenceContext annotations providing convenient
access to EntityManagerFactory/EntityManager -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<!-- transaction manager for use with a single JPA EntityManagerFactory for transactional data access
to a single datasource -->
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- enables interpretation of the #Transactional annotation for declerative transaction managment
using the specified JpaTransactionManager -->
<tx:annotation-driven transaction-manager="jpaTransactionManager" proxy-target-class="false"/>
</beans>
Now, when I try to run this, I get the following:
SEVERE: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener#fa60fa6] to prepare test instance [null(mil.navy.ndms.conops.common.dao.impl.MenuItem_Junit4_JPATest)]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mil.navy.ndms.conops.common.dao.impl.MenuItem_Junit4_JPATest': Injection of resource fields failed; nested exception is java.lang.IllegalStateException: Specified field type [interface javax.persistence.EntityManagerFactory] is incompatible with resource type [javax.persistence.EntityManager]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessAfterInstantiation(CommonAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:959)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:329)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:255)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:93)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:130)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:61)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:54)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:52)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.lang.IllegalStateException: Specified field type [interface javax.persistence.EntityManagerFactory] is incompatible with resource type [javax.persistence.EntityManager]
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.checkResourceType(InjectionMetadata.java:159)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.(PersistenceAnnotationBeanPostProcessor.java:559)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$1.doWith(PersistenceAnnotationBeanPostProcessor.java:359)
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:492)
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:469)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:351)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:296)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:745)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:448)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(AccessController.java:219)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:168)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:435)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:537)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:180)
at org.springframework.beans.factory.annotation.InjectionMetadata.injectFields(InjectionMetadata.java:105)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessAfterInstantiation(CommonAnnotationBeanPostProcessor.java:289)
... 18 more
It seems to be telling me that its attempting to store an EntityManager object into an EntityManagerFactory field, but I don't understand how or why. My DAO classes accept both an EntityManager and EntityManagerFactory via the #PersistenceContext attribute, and they work find if I load them up and run them without the #ContextConfiguration attribute (i.e. if I just use the XmlApplcationContext to load the DAO and the EntityManagerFactory directly in setUp ()).
Any insights would be appreciated.
These are the correct combinations of annotation + interface:
#PersistenceContext
private EntityManager entityManager;
#PersistenceUnit
private EntityManagerFactory entityManagerFactory;
But when using spring's transaction and entity manager support, you don't need the EntityManagerFactory at all.
The reason why you don't need EntityManagerFactory is because the creation of the EntityManager is responsibility of the transaction manager. Here's what happens in short:
the transaction manager is triggered before your methods
the transaction manager gets the EntityManagerFactory (it is injected in it), creates a new EntityManager, sets in in a ThreadLocal, and starts a new transaction.
then it delegates to the service method
whenever #PersistenceContext is encountered, a proxy is injected (in your Dao), which, whenever accessed, gets the current EntityManager which has been set in the ThreadLocal
I had to do the below combination, apart from adding spring-aspects jar to the project properties->Aspect Path and enabling spring aspects in sts. Ofcourse in my application context config file i defined the Entitymanagerfactory.
#ContextConfiguration(locations = { "/META-INF/spring/applicationContext-domain.xml" })
public class ReaderTest extends AbstractJUnit4SpringContextTests {
#PersistenceContext
private EntityManager entityManager;
I too have same problem, When I added java-persistence api problem got resolved.
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>

Resources