tags:

views:

8624

answers:

4

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?

A: 

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.

Rich Kroll
A: 

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.

Michael Wiles
A: 

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>
A: 

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")
billy vandory
Huh? The optional `name` attribute of `@PersistenceContext` is used to look up the injected entity manager. **It has no corresponding element in `persistence.xml`**. If this worked for you, this is IMO just a lucky side effect related to the absence of `unitName` (the behavior in this case is vendor-specific). But this is not correct.
Pascal Thivent