1
votes

I'm new to Java EE 6, and even newer to Spring. I'm trying to inject an EclipseLink JPA EntityManager, and am exploring different ways of achieving this. I'm using Glassfish and Derby. In the examples below I'm trying to inject the EntityManager directly into a servlet or controller for simplicity, in practice I will have a DAO class that wraps the EntityManager.

In Java EE 6, I can define a servlet as follows:

@WebServlet(urlPatterns="/app/*")
public class FrontController extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @PersistenceContext
    private EntityManager entityManager;
}

The EntityManager is correctly injected with no further configuration.

Now I want to use Spring, ideally through annotations. Currently, I can define a Controller as follows:

@Controller
@RequestMapping("/testurl.htm")
public class ExampleController {
    private EntityManager em;

    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        this.em = em;
    }
}

In order for Spring to wire things up correctly, I need to include the following directive in my application context xml file:

<bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="myPU"/>
</bean>

If I don't include the snippet above, I get an exception on deploy: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 0

Having read this I was under the impression I wouldn't need the above XML snippet. Could anyone confirm if the above snippet will always be required?

Is there another approach - if an EntityManager is successfully injected to my FrontController servlet by the Java EE container, how can this same EntityManager be injected into my Spring application context and made available to other spring beans?

1
inject your em into service layer, not your controllers - NimChimpsky

1 Answers

0
votes

inject your em into service layer, not your controllers.

A brief snippet (using hibernate4) :

@Controller
public class AdminController {

    @Resource(name = "companyService")
    private CompanyService companyService;

    @RequestMapping(value = "/AllCompanies", method = RequestMethod.GET)
    public String getCompanies(final Model model) {
    final List<Company> companies = companyService.getAllCompanies();
    //dostuff
    }

and service :

@Service("companyService")
@Transactional
public class CompanyService {

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    @Transactional(readOnly = true)
    public List<Company> getAllCompanies() {
    final Session session = sessionFactory.getCurrentSession();
//... do stuff
}

and relevant bit of app context

<bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
        p:dataSource-ref="dataSource" p:configLocation="WEB-INF/classes/hibernate.cfg.xml"
        p:packagesToScan="com.mypackage" />

    <!-- Declare a datasource that has pooling capabilities -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        ... />

    <!-- Declare a transaction manager -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" 
                p:sessionFactory-ref="sessionFactory" />