I need to execute SQL script before PropertyPlaceholderConfigurer is initialized in Spring's context, as soon as application properties are stored in the database and this script should insert them. But currently placeholder is initialized earlier, which leads to errors.
Is there a way to execute <jdbc:initialize-database data-source="dataSource" ... before <bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" ... in Spring?
Or is there a way to initialize placeholderConfig bean later? I tried to use depends-on, lazy-init attributes for this bean, but it didn't help. Thanks in advance.
Another solution without creating any Bean:
If you've got one <jdbc:initialize-database /> you can add this property depends-on="org.springframework.jdbc.datasource.init.DataSourceInitializer#0" to your bean <bean id="placeholderConfig" />
If you have more than one <jdbc:initialize-database /> adapt the #0.
Here is how I solved that. I created a class Initializer. This class in its constructor executes plain old sql statements (java.sql.Statement), creates table (if it doesn't exist), and inserts properties (if they are not there). The dataSource bean is passed in the context to this constructor, and placeholderConfig bean uses depends-on="initializerBean". So, properties appear in the database before they are used.
This script
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc">
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:database/drop_schema.sql" />
<jdbc:script location="classpath:database/create_schema.sql" />
<jdbc:script location="classpath:database/sample_data.sql"/>
</jdbc:initialize-database>
<!-- Other bean definitions -->
</bean>
is essentially a shortcut to
<bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer" id="dataSourceInitializer">
<property name="databasePopulator" ref="resourceDatabasePopulator"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="resourceDatabasePopulator"
class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
<property name="scripts">
<array>
<value>classpath:database/drop_schema.sql</value>
<value>classpath:database/create_schema.sql</value>
<value>classpath:database/sample_data.sql</value>
</array>
</property>
</bean>
Note that I've added id to the DataSourceInitializer bean. Now you can reference it in PropertyPlaceholderConfigurer's depends-on attribute. That way you declare that your PropertyPlaceholderConfigurer should be created after DataSourceInitializer.
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="dataSourceInitializer"/>
In my case db was initialized after the LocalContainerEntityManagerFactoryBean had been created and Hibernate was unable to validate my schema.
The documentation explains how to deal with these problems:
http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch12s09.html
12.9.1.1 Initialization of Other Components that Depend on the Database
Our use case was arguably even more complex. We're using flyway for database migrations and it needs to be started before the entityManagerFactory is created. The problem for us was that <jdbc:initialize-database /> was only used in our migration tests and thus initialized in a different application context than flyway and the entityManagerFactory. So we couldn't simply use L. BIZE answer and let our flyway bean depend on org.springframework.jdbc.datasource.init.DataSourceInitializer#0 because it might not exist (i.e. in production it doesn't exist). We ended up creating a custom factory bean like this:
class OptionalBeanInitializer extends AbstractFactoryBean implements BeanFactoryAware {
private String beanName;
private BeanFactory beanFactory;
#Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
#Override
public Class<?> getObjectType() {
return OptionalBeanInitializer.class;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
#Override
protected Object createInstance() throws Exception {
if (beanFactory.containsBean(beanName)) {
// Initialize
beanFactory.getBean(beanName);
}
return new OptionalBeanInitializer();
}
}
Which we could use to depend on our optional dependency like this:
<bean id="optionalDataSourceInitializer" class="com.x.y.z.OptionalBeanInitializer">
<property name="beanName" value="org.springframework.jdbc.datasource.init.DataSourceInitializer#0"/>
</bean>
<bean id="flyway" class="com.googlecode.flyway.core.Flyway" init-method="migrate" depends-on="optionalDataSourceInitializer">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"
depends-on="flyway, optionalDataSourceInitializer">
<property name="dataSource" ref="dataSource"/>
</bean>
The OptionalBeanInitializer will take care of initializing the org.springframework.jdbc.datasource.init.DataSourceInitializer#0 bean only if it exists.
There are two simpler ways to add the depend-on attribute only for test context, and not for production context.
1/Override the bean in the test context.
In our case here is the production context :
<bean id="placeholderConfig" />
And the unit test context :
<bean id="placeholderConfig" depends-on="org.springframework.jdbc.datasource.init.DataSourceInitializer#0" />
Make sure that the unit test context is loaded before the production context and the good placeholderConfig bean will be instanciated, after the jdbc:initialize-database phase.
2/Another way is to use profiles
<beans profile="!test">
<bean id="placeholderConfig" .../>
</beans>
<beans profile="test">
<jdbc:initialize-database data-source="dataSource" .../>
<bean id="placeholderConfig" depends-on="org.springframework.jdbc.datasource.init.DataSourceInitializer#0" .../>
</beans>
Related
Like described in the linked article below, with Java configuration it is possible to override the JobRepository bean by extending DefaultBatchConfigurer and overriding createJobRepository.
How can this be achieved in a context.xml file where the jobrepository bean is defined like this
<bean id="jobRepository_new"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="databaseType" value="Oracle" />
<property name="dataSource" ref="dataSource-batch" />
<property name="transactionManager" ref="transactionManager" />
<property name="tablePrefix" value="BATCH_" />
<property name="lobHandler" ref="oracleLobHandler" />
</bean>
?
Can't serialize access for this transaction when running single job, SERIALIZED isolation level
Unlike with the Java configuration style, there is nothing provided by default (that you can override) when you use the XML configuration style.
So you just need configure the job repository bean as needed like shown in the snippet you shared.
I have the project structure as following -
Facade -> Service-> DAO
In the DAO layer, when the beans are initialized then many dependencies are injected from a property file. Therefore, the properties file must be read first and then the remaining dao beans must be created. When the application is started then it gives an error that Spring cannot resolve a placeholder.
The DAO-application-context.xml is like-
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="prop">
<value>app.properties</value>
</property>
</bean>
<import resource = "a-dao.xml" />
<import resource = "b-dao.xml" />
<import resource = "c-dao.xml" />
Now in all the child application contexts i.e. a-dao, etc, we have-
<bean ....>
<property name = "xyz">
<value>${appValue}<value/>
</property>
<bean>
The error received is that appValue cannot be resolved. I think that it may be due to incorrect sequence of bean creation. However, the same config is working in another larger project.
I have checked Order of Spring Bean Initialization but implementing that solution would not be feasible. Is there any other way ?
Reg this Block of Configuration, property prop seems to be wrong
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="prop">
<value>app.properties</value>
</property>
</bean>
According to the Spring documentation
You could use the property location or locations to set the one or multiple values of the properties file.
So the code should be refactored to
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>app.properties</value>
</property>
</bean>
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.
I'm new to Spring's transaction management having troubles to tackle the following scenario of nested transactions while integrating Spring (3.2) and Hibernate (3.6).
I've declared two appContext files as following.
File1) applicationContext-student.xml
<bean id="studentProjSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
...**dataSource1_on_Machine1**...
</bean>
<bean id="studentProjTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="studentProjSessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="studentProjTransactionManager" />
<bean id="studentDao" class="com.my.univ.employee.dao.studentHibDao" scope="singleton" />
<bean id="studentService" class="com.my.univ.student.service.studentServiceImpl" scope="singleton">
<property name="studentDao" ref="studentDao" />
</bean>
File2) applicationContext-employee.xml
<bean id="employeeProjSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
........**dataSource2_on_Machine2**...
</bean>
<bean id="employeeProjTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="employeeProjSessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="employeeProjTransactionManager" />
<bean id="employeeDao" class="com.my.univ.employee.dao.EmployeeHibDao" scope="singleton" />
<bean id="employeeService" class="com.my.univ.employee.service.EmployeeServiceImpl" scope="singleton">
<property name="employeeDao" ref="employeeDao" />
</bean>
Imported above two files in the following file.
File3) applicationContext-university.xml
<import resource="applicationContext-student.xml" />
<import resource="applicationContext-employee.xml" />
<bean id="personService" class="com.my.univ.person.service.PersonServiceImpl" scope="singleton">
<property name="studentService" ref="studentService" />
<property name="employeeService" ref="employeeService" />
</bean>
Questions
Let's assume that method level #Transactional annotations are provided with the right txManager names in studentService and employeeService but not in personService.
Q1) If I declare a method in personService as #Transactional, which txManager gets picked?
Q2) How does the nested txManager scenario work if the txManagers in the hierarchy are different from each other?
Ex: If a #Transactional method in personService invokes a #Transactional method in studentService and then another #Transactional method in employeeService (with in the same method of personService).
Q3) How does the commit, rollback elements work in above scenario.
Q4) Readonly operations vs Read/Write operations in above scenario.
It'd be great if anybody could clarify the above.
Thanks.
The #Transactional annotation takes as a value the bean name of the transaction manager. From the documentation:
public abstract String value
A qualifier value for the specified transaction.
May be used to determine the target transaction manager, matching the qualifier value (or the bean name) of a specific PlatformTransactionManager bean definition.
Default:
""
So in your case, explicitly defining:
#Transactional("studentProjTransactionManager")
#Transactional("employeeProjTransactionManager")
should wrap transactionally using the right transaction manager.
I'm trying to set up a Spring JPA Hibernate simple example WAR for deployment to Glassfish.
I see some examples use a persistence.xml file, and other examples do not.
Some examples use a dataSource, and some do not. So far my understanding is that a dataSource is not needed if I have:
<persistence-unit name="educationPU"
transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.coe.jpa.StudentProfile</class>
<properties>
<property name="hibernate.connection.driver_class"
value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url"
value="jdbc:mysql://localhost:3306/COE" />
<property name="hibernate.connection.username" value="root" />
<property name="show_sql" value="true" />
<property name="dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
I can deploy fine, but my EntityManager is not getting injected by Spring.
My applicationContext.xml:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="educationPU" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="StudentProfileDAO" class="com.coe.jpa.StudentProfileDAO">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="studentService" class="com.coe.services.StudentService">
</bean>
My class with the EntityManager:
public class StudentService {
private String saveMessage;
private String showModal;
private String modalHeader;
private StudentProfile studentProfile;
private String lastName;
private String firstName;
#PersistenceContext(unitName="educationPU")
private EntityManager em;
#Transactional
public String save()
{
System.out.println("*** em: " + this.em); //em is null
this.studentProfile= new StudentProfile();
this.saveMessage = "saved";
this.showModal = "true";
this.modalHeader= "Information Saved";
return "successs";
}
My web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
Are there any pieces I am missing to have Spring inject "em" in to StudentService?
Just to confirm though you probably did...
Did you include the
<!-- tell spring to use annotation based congfigurations -->
<context:annotation-config />
<!-- tell spring where to find the beans -->
<context:component-scan base-package="zz.yy.abcd" />
bits in your application context.xml?
Also I'm not so sure you'd be able to use a jta transaction type with this kind of setup? Wouldn't that require a data source managed connection pool? So try RESOURCE_LOCAL instead.
I'm confused. You're injecting a PU into the service layer and not the persistence layer? I don't get that.
I inject the persistence layer into the service layer. The service layer contains business logic and demarcates transaction boundaries. It can include more than one DAO in a transaction.
I don't get the magic in your save() method either. How is the data saved?
In production I configure spring like this:
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/ThePUname" />
along with the reference in web.xml
For unit testing I do this:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource" p:persistence-xml-location="classpath*:META-INF/test-persistence.xml"
p:persistence-unit-name="RealPUName" p:jpaDialect-ref="jpaDialect"
p:jpaVendorAdapter-ref="jpaVendorAdapter" p:loadTimeWeaver-ref="weaver">
</bean>
If anyone wants to use purely Java configuration instead of xml configuration of hibernate, use this:
You can configure Hibernate without using persistence.xml at all in Spring like like this:
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
Map<String, Object> properties = new Hashtable<>();
properties.put("javax.persistence.schema-generation.database.action",
"none");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); //you can change this if you have a different DB
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(adapter);
factory.setDataSource(this.springJpaDataSource());
factory.setPackagesToScan("package name");
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
factory.setValidationMode(ValidationMode.NONE);
factory.setJpaPropertyMap(properties);
return factory;
}
Since you are not using persistence.xml, you should create a bean that returns DataSource which you specify in the above method that sets the data source:
#Bean
public DataSource springJpaDataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:mysql://localhost/SpringJpa");
dataSource.setUsername("tomcatUser");
dataSource.setPassword("password1234");
return dataSource;
}
Then you use #EnableTransactionManagement annotation over this configuration file. Now when you put that annotation, you have to create one last bean:
#Bean
public PlatformTransactionManager jpaTransactionManager()
{
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject());
}
Now, don't forget to use #Transactional Annotation over those method that deal with DB.
Lastly, don't forget to inject EntityManager in your repository (This repository class should have #Repository annotation over it).
I have a test application set up using JPA/Hibernate & Spring, and my configuration mirrors yours with the exception that I create a datasource and inject it into the EntityManagerFactory, and moved the datasource specific properties out of the persistenceUnit and into the datasource. With these two small changes, my EM gets injected properly.
This may be old, but if anyone has the same problem try changing unitname to just name in the PersistenceContext annotation:
From
#PersistenceContext(unitName="educationPU")
to
#PersistenceContext(name="educationPU")