In our application, we want to set multiple data source with Spring and JPA. Hence we have created 2 entityManagerFactory, 2 data source and 2 transaction- manager.
web.xml
<param-value>
/WEB-INF/a_spring.xml
/WEB-INF/b_spring.xml
</param-value>
Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="db1" transaction-type="RESOURCE_LOCAL">
<class>com.rh.domain.RcA</class>
</persistence-unit>
<persistence-unit name="db2" transaction-type="RESOURCE_LOCAL">
<class>com.rh.domain.Rcb</class>
</persistence-unit>
</persistence>
a_spring.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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-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 = "RcMaintenanceService" class="com.rh.services.RcAbcMaintenanceServiceImpl" autowire="byName" />
<aop:config>
<aop:pointcut id="rOperation" expression="execution(* com.rh.services.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="rOperation"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/db1" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="db1" />
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
<property name="database" value="MYSQL" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect">
</bean>
</property>
</bean>
I also declare another entityManagetFactory,Transaction Manager and dataSource to b_spring.xml.
Error
Initialization of bean failed; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
unique bean of type [javax.persistence.EntityManagerFactory] is
defined: expected single bean but found 2 Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
unique bean of type [javax.persistence.EntityManagerFactory] is
defined: expected single bean but found 2 at
org.springframework.beans.factory.BeanFactoryUtils.beanOfTypeIncludingAncestors(BeanFactoryUtils.java:303)
at
org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:451)
at
org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:428)
at
org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$AnnotatedMember.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:582)
at
org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$AnnotatedMember.resolve(PersistenceAnnotationBeanPostProcessor.java:553)
at
org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$AnnotatedMember.inject(PersistenceAnnotationBeanPostProcessor.java:489)
In case of multiple data source configuration, we need to define which one will be considered as a primary data source. we can specify that using #Primary annotation in java config or primary=true in XML bean config.
As there is two entity manager being created in XML, we need to use #Qualifier to specify which bean should be injected where. In your case, something like this.
#PersistenceContext(unitName = "db1")
public void setEntityManager(#Qualifier("entityManagerFactory") EntityManager entityMgr) {
this.em = entityMgr;
}
for XML configuration, we can do something like this
<bean id="BaseService" class="x.y.z.BaseService">
<property name="em" ref="entityManagerFactory"/>
<property name="em1" ref="entityManagerFactory1"/>
</bean>
<bean id = "RcMaintenanceService" class="com.rh.services.RcAbcMaintenanceServiceImpl" autowire="byName" parent="BaseService"/>
Did you try providing the package details which contains your EntityManagerFactory bean?
You can provide the package details as a property in you bean definition -
<property name="packagesToScan" value="com.XX.XX.XX.XX" />
new property to be added in this block -
<bean id="entityManagerFactory1" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="db2" />
<property name="dataSource" ref="dataSource1"/>
<-- add here for both beans -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
<property name="database" value="MYSQL" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect">
</bean>
</property>
</bean>
Also, you are missing the persistenceXmlLocation property -
<property name="persistenceXmlLocation" value="***/persistence.xml" />
The error message you've posted indicates that you're autowiring by type for an object of type EntityManagerFactory. None of the code you've shown so far contains such an injection, which implies that it's probably in some code you haven't yet posted.
If you were to post the full stack trace of the error, you'd be able to walk up the stack to see which bean contains the un-satisfiable reference to an EntityManagerFactory object, which in turn would let you change how you're referencing it to allow a reference to the specific bean you want.
Update
Based on the further information you provided (thank you) and some Googling, it seems as though other users have similarly found that specifying a unitName isn't enough to get the correct EntityManager injected. Several posts online back up #lucid's recommendation to use the #Qualifier annotation to get Spring to select the correct bean, but unfortunately that annotation was introduced in 2.5 so it's only available to you if you upgrade. (Which, given the age of the Spring framework that you're using, is probably a good idea, but that's a separate conversation.)
However, several users have indicated that an alternate approach is available in 2.0.5, using a single PersistenceUnitManager that references multiple data sources rather than multiple persistence units that each reference a single data source. From the official Spring docs: https://docs.spring.io/spring/docs/2.0.x/reference/orm.html#orm-jpa-multiple-pu.
Overall I'd suggest you consider upgrading to a version of Spring that's not more than a decade old, which would let you specify an #Qualifier annotation per #lucid's answer. But if that's not possible for some reason, the PersistenceUnitManager approach should give you a way to make it work within Spring 2.0.5.
There are a couple of things that don't look good to me. The name of the setters won't match the property names, I think that is important, the second thing is about the inheritance, some annotations sometimes only works in concrete classes not in base classes. I would try to change the base service as follow.
public class BaseService {
#PersistenceContext(unitName = "db2")
private EntityManager em;
#PersistenceContext(unitName = "db1")
private EntityManager em1;
public EntityManager getEm() {
return em;
}
protected EntityManager getEm2() {
return em1;
}
public void setEm(EntityManager entityMgr) {
this.em = entityMgr;
}
public void setEm1(EntityManager entityMgr) {
this.em = entityMgr;
}
}
If that does not work I probably try to remove the base class and see if I put the annotation under the concrete class I can make that works, I would do that moving just the annotations to the RcAbcMaintenanceServiceImpl class and remove the extend statement that inherits from the BaseService
Also, I noticed that the PersistenceContext annotation has another param https://docs.oracle.com/javaee/6/api/javax/persistence/PersistenceContext.html, so you could try to use the name as well to match the id on the bean definition.
Related
I am trying to sort out the following issue.
I've created a Spring Boot application which is also using Spring Data.
To do integration tests, I want to power up an H2 database.
I configured the test with #ContextConfiguration and referenced my applicationContext.xml file.
When I am running the tests out of the IDE (intelliJ) everything is fine, and the test is getting grean.
But as soon as I run the test on my build server or in the console with gradle, I get NoSuchBeanDefinitionException. It seems like the applicationContext is not considered at all...
Actually I have no clue anymore what to do..
My applicationContext-test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:data="http://www.springframework.org/schema/data/jpa"
xmlns="http://www.springframework.org/schema/beans"
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.xsd">
<context:annotation-config/>
<context:component-scan base-package="de.company.project"/>
<bean class=
"org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean class=
"org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence-
test.xml"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect"/>
</bean>
</property>
</bean>
</beans>
My persistenc-test.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit"
transaction-type="RESOURCE_LOCAL">
<class>de.company.project.server.model.Entity</class>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.ejb.naming_strategy"
value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.default_schema" value="public" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
The database.properties just contains the defaults for an H2 database.
And last but not least my Testclass
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:*META-INF/applicationContext-test.xml")
public class EntityServiceTest {
#Test
public void doSomeStuff(){
}
.
.
}
I hope somebody has a clue what I am doing wrong?!
BR
Edit:
Missed to add the exception and the respository:
#Repository
public interface EntityRepository extends JpaRepository<Entity, Integer> {
}
Exception:
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying
bean of type [de.company.project.server.dao.EntityRepository] 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)}
I fixed it by adding TransactionalTestExecutionListener.class to my TestExecutionListeners.
I think the #Repository annotation should be on the implementation and not the interface. I assume you have this interface #Autowired somewhere else. Spring needs to know which concrete class should be used.
Also, the config file may not be found on the classpath with unit tests. Place the test context config in src/test/resources and change the configuration annotation to:
#ContextConfiguration(locations = "classpath:/applicationContext-test.xml")
See this answer (and others for the same question) for more info: https://stackoverflow.com/a/4377840/3851006
According to its JavaDoc, PersistenceAnnotationBeanPostProcessor seems to be responsible for injecting the EntityManager with the annotation #PersistenceContext. It appears to imply without this bean declared in the Spring application context xml, the #PersistenceContext annotation won't work.
However, based on my experiments, this is not the truth.
Persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="default" transaction-type="RESOURCE_LOCAL" />
</persistence>
Spring application context XML
<context:component-scan base-package="com.test.dao" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="default"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect"/>
</bean>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="url" value="jdbc:derby://localhost:1527/c:\derbydb\mydb"/>
<property name="username" value="APP"/>
<property name="password" value="APP"/>
</bean>
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!--
<bean id="persistenceAnnotation" class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
-->
UserDaoImpl
#Repository("userDao")
public class UserDaoImpl implements UserDao {
#PersistenceContext
protected EntityManager entityManager;
#Transactional
public void save(User user) {
entityManager.persist(user);
}
}
Whether I comment or uncomment the persistenceAnnotation bean, the result is the same. It doesn't hurt to leave the bean around, but what's the use of this bean?
I am using Spring 3.0.5.
Could someone provide a scenario where taking out this bean will result in failure?
Also I am not fond of creating an empty persistence unit just to fool Spring. Luckily this problem has been addressed in Spring 3.1.0.
The PersistenceAnnotationBeanPostProcessor transparently activated by the <context:component-scan /> element. To be precise it's the <context:annotation-config /> element that activates the bean but this element in turn gets transparently activated by <context:component-scan />.
As Oliver Gierke mentioned, org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor is automatically loaded into App Context by Spring when using annotation based configuration. One of its duties is to search the proper entity EntityManagerFactory that would provide the EntityManager for you #PersistenceContext annotated properties.
If you have multiple EntityManagerFactory beans in you spring config/context and you have #PersistenceContext annotations without a unitName attribute (lets say you are using a framework that comes with such a bean, and you can't touch framework code), you may run into this exception: org.springframework.beans.factory.NoUniqueBeanDefinitionException.
I found this workaround in case you tun into this:
<bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" >
<property name="defaultPersistenceUnitName" value="entityManagerFactory"/>
</bean>
This would override the default PersistenceAnnotationBeanPostProcessor loaded by Spring with a new one with defaultPersistenceUnitName.
I need to do very similar thing to what is described in Injecting Entitymanager via XML and not annnotations, but I need to inject from XML the real, container-created, entity manager, so that it behaves exactly as if there is a real #PersistenceContext annotation. I've found a LocalEntityManagerFactoryBean (notice missing "Container" word), but I'm affraid that it creates a new entity manager factory and therefore entity manager won't be compatible with that injected via real #PersistenceContext annotation.
I will describe the reason, because it is weird and maybe the solution to my problem is to choose completely different approach. I'm using PropertyPlaceholderConfigurer in my spring configuration and in this configurer I'm referencing other beans. I'm experiencing a bug that autowiring doesn't work in those referenced beans. I don't know why and how PropertyPlaceholderConfigurer turns off autowiring in those referenced beans but the fact is, that if I replace autowiring by xml configuration for those beans, everything works. But I'm unable to replace autowiring of EntityManager, since it's not standard spring bean, but jndi-loaded something I don't fully understand.
One way or the other, is there some solution?
in spring-bean.xml ,
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="USER_TEST"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/>
</property>
<property name="jpaPropertyMap">
<props>
<prop key="eclipselink.weaving">false</prop>
</props>
</property>
<bean id="PersonDao" class="com.xxx.java.person.persistence.PersonDAO">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="earlyInitializedApplicationSettingsService" class="...services.impl.ApplicationSettingsServiceImpl" autowire-candidate="false">
<property name="applicationSettingsDao">
<bean class="....impl.ApplicationSettingsDaoImpl">
<property name="entityManager">
<bean class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory">
<bean class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/persistence/somePersistenceUnit"/>
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
Notice mainly the fact, that I'm not using standard jee:jndi-lookup, because it didn't work (in the conditions created by PropertyPlaceholderConfigurer) and that was the source of my confusion. When I used direct JndiObjectFactoryBean, it worked.
I understand that this is a very long question, but i wanted to ask everything because i'm
stuck with these things for more than 2 weeks and i'm in a situation to solve this within
this week. Please guide me in this matter.
I'm Using EclipseLink jpa version 2, Spring 3, jdk6, MySQL5 and tomcat7.
I have configured the following in each of my DAO classes.
#PersistenceContext
private EntityManager em;
I have the following in my Spring xml:
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="url" value="jdbc:mysql://localhost:3306/xxxxx"/>
<property name="username" value="xxxx"/>
<property name="password" value="xxxx"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" >
<property name="showSql" value="true"/>
<property name="generateDdl" value="true" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/>
From Persistence.xml:
<persistence-unit name="xxxxx" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<-- class mappings -->
</persistence-unit>
I've got few confusion about what i have done:
Is the EntityManager injected by Spring? (I understand that #PersistenceContext is a
J2EE annotation, so wondering whether it is injected without Spring's contribution).
As i have already mentioned, i have injected EntityManager in all the DAO classes. Is
this a good practice? or should i make it Singleton by having a separate class like
PersistenceManager, which has EntityManager attribute wired, and have
getEntityManager() method?
As you can see above, i have configured Spring transactions. But when i do CRUD
operations continuously for 2-3 times, application gets stuck and fails with EclipseLink
exception saying unable to get lock, timeout etc. Am i doing anything wrong here or
missing any transaction configurations??
With the above configurations, i can only use #Transactional annotation with default
values which are PROPAGATION_REQUIRED,ISOLATION_DEFAULT. If i change these for any other
values, such as #Transactional(PROPAGATION_REQUIRED,ISOLATION_SERIALIZABLE) etc,
application throws exception as Custom isolation levels are not supported. Again, am
i missing any configurations?
Thanks.
Yes, spring recognizes the #PersistenceContext annotation and injects the entity manager
Spring takes care of that - it injects the same EntityManager instance in all DAOs. In fact, it injects a proxy so that each request uses a different entity manager.
Normally everything should run fine. You need <tx:annotation-driven /> in order to use #Transactional
JPA only supports the default isolation level. You can work this around by customizing the spring jpa dialect, but there's nothing built-in. The way to go is extend XJpaDialect (in your case X=EclipseLink), override the beingTransaction, obtain the Connection (in an eclipse-link specific way), set the desired isolation level (accessible through the transaction definition), and configure this as a property of your LocalContainerEntityManagerFactoryBean:
<property name="jpaDialect">
<bean class="com.foo.util.persistence.EclipseLinkExtendedJpaDialect" />
</property>
I am using JUnit 4 to test Dao Access with Spring (annotations) and JPA (hibernate). The datasource is configured through JNDI(Weblogic) with an ORacle(Backend). This persistence is configured with just the name and a RESOURCE_LOCAL transaction-type
The application context file contains notations for annotations, JPA config, transactions, and default package and configuration for annotation detection.
I am using Junit4 like so:
ApplicationContext
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="workRequest"/>
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${database.target}"/>
<property name="showSql" value="${database.showSql}" />
<property name="generateDdl" value="${database.generateDdl}" />
</bean>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>workRequest</value>
</property>
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">t3://localhost:7001</prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
JUnit TestCase
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class AssignmentDaoTest {
private AssignmentDao assignmentDao;
#Test
public void readAll() {
assertNotNull("assignmentDao cannot be null", assignmentDao);
List<Assignment> assignments = assignmentDao.findAll();
assertNotNull("There are no assignments yet", assignments);
}
}
regardless of what changes I make I get:
No unique bean of type [javax.persistence.EntityManager] is defined
Any hint on what this could be. I am running the tests inside eclipse.
Your Spring context has a bean definition using LocalContainerEntityManagerFactoryBean. This creates an EntityManagerFactory, not an EntityManager.
AssignmentDao needs to get itself wired with an EntityManagerFactory.
Alternatively, you can replace the LocalContainerEntityManagerFactoryBean with a LocalEntityManagerFactoryBean, which will create an EntityManager directly. However, you need to be careful with that one, it has some downsides. See that part of the Spring docs for a full explanation of the options.
It's confusing, because the naming conventions of JPA and Spring overlap each other, so naming these classes is a real bugger.