[RESOLVIDO] Spring + JPA injetando o entityManagerFactory

Olá pessoal, estou tentando utilizar o Spring com o JPA, porém não estou conseguindo fazer a injeção de dependencia do entityManagerFactory, estou urilizando uma aplicação web, será que alguem pode me ajudar?

jps-servlet.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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.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 name="/hello.htm" class="orm.controller.Teste" />
	
	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>        
    </bean>
    	
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="loadTimeWeaver">
			<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
		</property>
	</bean>
	
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>

web.xml

<servlet>
    <servlet-name>jpa</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>jpa</servlet-name>
    <url-pattern>*.htm</url-pattern>
  </servlet-mapping>
  
  <context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		/WEB-INF/jpa-servlet.xml
	</param-value>
  </context-param>

classe Product

@Entity
public class Product {

	private int id;
	private String name;
	
	public Product() {
	}
	
	@SequenceGenerator(name = "generator", sequenceName = "seq_product", allocationSize = 1)
	@Id
	@GeneratedValue(strategy = SEQUENCE, generator = "generator")
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

ProductDAO

[code]@PersistenceContext
public class ProductDAO {

@PersistenceUnit
private EntityManagerFactory _entityManagerFactory = null;
private EntityManager _entityManager = null;

public ProductDAO() {
	_entityManager = _entityManagerFactory.createEntityManager();
}

public void insert(Product product) {
	_entityManager.getTransaction().begin();
	_entityManager.persist(product);
	_entityManager.getTransaction().commit();
}

public void delete(Product product) {
	_entityManager.getTransaction().begin();
	_entityManager.remove(product);
	_entityManager.getTransaction().commit();
}

public void update(Product product) {
	_entityManager.getTransaction().begin();
	_entityManager.merge(product);
	_entityManager.getTransaction().commit();
}

public Product findByPK(Object obj) {
	return _entityManager.find(Product.class, obj);
}

public ArrayList<Product> findAll() {
	Query query = _entityManager.createQuery("from Product" );
	
	return (ArrayList<Product>) query.getResultList();
}

public EntityManagerFactory get_entityManagerFactory() {
	return _entityManagerFactory;
}

public void set_entityManagerFactory(EntityManagerFactory managerFactory) {
	_entityManagerFactory = managerFactory;
}

public EntityManager get_entityManager() {
	return _entityManager;
}

public void set_entityManager(EntityManager manager) {
	_entityManager = manager;
}

}
[/code]

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="maindatabase" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider> 
		<properties>
			<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" /> 
			<property name="hibernate.connection.username" value="postgres" /> 
			<property name="hibernate.connection.password" value="database" /> 
			<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/exemplo" /> 
			<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> 
			<property name="hibernate.show_sql" value="true" /> 
		</properties>
	</persistence-unit>
</persistence>

classe Teste

public class Teste implements Controller{

	protected final Log logger = LogFactory.getLog(getClass());

	@Override
	public ModelAndView handleRequest(HttpServletRequest arg0,
			HttpServletResponse arg1) throws Exception {
		
		
		ProductDAO productDAO = new ProductDAO();
		
		Product product = new Product();
		product.setName("Teste");
		
		productDAO.insert(product);
		
        String now = (new Date()).toString();
        logger.info("Returning hello view with " + now);

        return new ModelAndView("hello", "now", now);

	}
}

Pessoal quando eu o chamo pelo metodo main a dependencia é feita normalmente, funciona bunitinho:

public static void main(String[] args) {
		
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("jpa-servlet.xml");  
		
		ProductDAO productDAO =(ProductDAO) applicationContext.getBean("productDAO");
		
		Product product = new Product();
		product.setName("Teste");
		
		productDAO.insert(product);
		
	}

Não consigo fazer a dependencia fodando pelo servidor, alguem ai pode me ajudar?

O Spring é um framework poderoso. Você realmente precisa injetar o EntityManagerFactory nos seus beans?

Você já ouviu falar no conceito “Open Session/EntityManager in View”?
O Spring pode fazer isso por você: org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter

	<filter>
		<filter-name>inviewr</filter-name>
		<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>inview</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

Depois você poderia usar apenas os seus DAOs assim:

	@PersistenceContext
	private EntityManager entityManager;

E colocar a Annotation @Transactional nos métodos que dependem de uma transação (se não souber o suficiente sobre transactions no Spring, da uma olhada na net).

	@Transactional
	public void delete(EntityClass entity) {
		entityManager.remove(entity);
	}

Outra coisa, existe uma GRANDE diferença entre isso:

ProductDAO productDAO =(ProductDAO) applicationContext.getBean("productDAO");

e isso

ProductDAO productDAO = new ProductDAO();

Olá Guilherme, estou iniciando no spring agora, então não tenho experiência com este framework, preciso fazer a integração do Spring com JPA, estou me baseando nesta parte da documentação http://static.springframework.org/spring/docs/2.0.x/reference/orm.html e em alguns pequenos tutoriais que vi na net, porem nao vi nenhum exemplo completo e pouca coisa falando de JPA puro com Spring.

Como já te disse tenho pouco conhecimento do Spring, até agora tinha entendido que ele funciona desta maneira, gerenciando as dependências através dos beans, não sabia que teria outra forma além desta.

Não tenho o conhecimento deste conceito, e como devo utilizar além de mapear os filtros no web.xml? Ele vai criar o EntityManagerFactory Automaticamente, vai ser necessários o mesmo mapeamento nos beans?

Quando comecei a estudar Spring fiz exempos utilizando aplicações desktop e utilizei a primiera forma pra fazer as injeções de dependência necessárias, agora que comecei a utilizar a parte web vi que isso é feito de forma diferente.

Desde já agradeço a atenção Guilherme.

Tentei implementar mas ocorreu a seguinte exception:

java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.tomcat.util.IntrospectionUtils.callMethod1(IntrospectionUtils.java:922)
	at org.apache.tomcat.util.digester.SetNextRule.end(SetNextRule.java:193)
	at org.apache.tomcat.util.digester.Rule.end(Rule.java:229)
	at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:1140)
        ....
        ....
        ....
Caused by: java.lang.IllegalArgumentException: Filter mapping specifies an unknown filter name inview
	at org.apache.catalina.core.StandardContext.addFilterMap(StandardContext.java:2160)
	... 37 more
04/05/2009 10:41:08 org.apache.catalina.startup.ContextConfig applicationWebConfig
SEVERE: Parse error in application web.xml file at jndi:/localhost/jpa/WEB-INF/web.xml
java.lang.IllegalArgumentException: Filter mapping specifies an unknown filter name inview
	at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:2808)
	at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:2834)
	at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:1143)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1774)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2930)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
        ....
        ....
        ....
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
04/05/2009 10:41:08 org.apache.catalina.startup.ContextConfig applicationWebConfig
SEVERE: Occurred at line 31 column 20

Você disse uma coisa muito importante, o Spring faz Injeção de Dependencias. Mas como ele pode fazer uma injeção de dependencia com você fazendo ProductDAO dao = new ProductDAO()?

Você deve chamar o Spring para pegar o DAO.

Usando o web.xml para declarar o XML do Spring, no meu caso é o seguinte:

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-config.xml, /WEB-INF/spring-security.xml, /WEB-INF/spring-core.xml
        </param-value>
    </context-param>

E nesses XMLs você declara as suas classes e suas dependencias (ou usa as annotations). Assim, quando algum Bean for acessado, a injeção de dependencia será automatica.

Agora, se estiver acessando seus beans via uma servlet você terá um problema, pois servlets são criadas pelo ServletContainer (Tomcat, Jetty, …). O jeito mais facil de acessar um bean via servlet é fazendo o seguinte:

ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
ProductDAO dao = (ProductDAO) context.getBean("ProductDAO ");

Existe uma servlet do spring que da forwarding pra sua servlet e todo um esquema que eu num gostei muito e não lembro mais como faz ^^
Se quiser, pode dar uma pesquisada por isso.

Então Guilherme, como estou fazendo apenas um exemplo primeiro, estou usando apenas o arquivo spring-servlet.xml que pelo que eu vi é default, é o que ele vai procurar caso nao seja especificado nenhum no context-param, correto?

Neste arquivo como eu ja postei acima eu declarei a minha DAO e o entityManagerFactory e também estou declarando a minha pagina que vai chamar a minha classe de “controle” onde eu chamo a DAO. É neste ponto que não estou conseguindo fazer a implementação acho que não é desta maneira que devo fazer, não sei se consegui expressar meu problema, mas ai qdo eu chamo a DAO da um NullPointer pois, a injeção não é feita, na minha coloquei as Annotation na DAO @PersistenceUnit no entityManagerFactory e @PersistenceContext em cima da declaração da minha classe, desta maneira qdo eu chama a aplicação como se fosse uma aplicação desktop, pelo método main funciona, mas qdo eu rodo com o Tomcat, pelo server a injeção não é feita.

Vou mostrar alguns trechos importantes de um código que tenho aqui:

Meu dao:

	@PersistenceContext
	private EntityManager entityManager;

web.xml

	<filter>
		<filter-name>transactionFilter</filter-name>
		<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>transactionFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

//...

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-config.xml, /WEB-INF/spring-security.xml, /WEB-INF/spring-core.xml
        </param-value>
    </context-param>
    
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>

arquivos de configuração do spring:

<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
	<context:component-scan base-package="br.com......." />

	<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver" />
		<property name="jdbcUrl" value="URL" />
		<property name="user" value="LOGIN" />
		<property name="password" value="SENHA/>
	</bean>

	<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="myDataSource" />
    </bean>

	<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="myDataSource" />
    </bean>

	<bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <!-- <property name="persistenceUnitName" value="nweb4"></property> -->
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.format_sql">false</prop>
            </props>
        </property>
        <property name="persistenceProvider">
        	<bean class="br.com.........interceptor.ConfigurableHibernatePersistence"> MEU PERSISTENTE PROVIDER
        		<property name="interceptor">
        			<bean class="br.com.......interceptor.LogInterceptor" />
        		</property>
        		<property name="postInsertEventListener" ref="logSaveOperation"></property>
        	</bean>
        </property>
    </bean>

No contexto WEB, você deve informar o Listener que inicia o ApplicationContext do Spring.
Não esqueça das coisas que ja postei…

no meu caso estou utilizando o persistence.xml para configuração do dataSource, mesmo assim eu preciso declarar de novo na configuração do Spring como vc fez? E este property chamado persistenceProvider pra que que serve? :slight_smile:

O arquivo persistence.xml é obrigatório, JPA exige que ele exista na pasta META-INF na raiz do classpath, no caso, o meu esta assim:

<?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="***" transaction-type="RESOURCE_LOCAL">
    	<!--provider>br.com.****.interceptor.ConfigurableHibernatePersistence</provider>
    	<provider>org.hibernate.ejb.HibernatePersistence</provider-->
    </persistence-unit>
</persistence>

Você não precisa declarar as propriedades no arquivo do spring caso esteja usando o persistence.xml. No meu caso, preferi declarar tudo no spring por uma questão de centralização de informações referentes ao banco.

Mas, mesmo que você utilize o persistence.xml, você precisa declarar a entityManagerFacory como o código que postei.

Quanto ao PersistenceProvider que postei, é uma solução que eu encontrei na internet para conseguir usar o Provider do Hibernate e ainda assim usar um interceptor com ele, injetado pelo Spring, com o provider padrão do hibernate não dá, tem que inserir via propriedades…

Fiz as configurações e alterações, apareceu a seguinte exception:
Será que é algum jar faltando?

SEVERE: Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/jpa-servlet.xml]; nested exception is java.lang.NoSuchMethodError: org.springframework.aop.config.AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(Lorg/springframework/beans/factory/xml/ParserContext;Lorg/w3c/dom/Element;)V
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:420)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:124)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:92)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:123)

...


Caused by: java.lang.NoSuchMethodError: org.springframework.aop.config.AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(Lorg/springframework/beans/factory/xml/ParserContext;Lorg/w3c/dom/Element;)V
	at org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser$AopAutoProxyConfigurer.configureAutoProxyCreator(AnnotationDrivenBeanDefinitionParser.java:109)
	at org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.parse(AnnotationDrivenBeanDefinitionParser.java:80)
	at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:69)


...


04/05/2009 14:19:41 org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/jpa-servlet.xml]; nested exception is java.lang.NoSuchMethodError: org.springframework.aop.config.AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(Lorg/springframework/beans/factory/xml/ParserContext;Lorg/w3c/dom/Element;)V
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:420)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:124)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:92)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:123)


...

Caused by: java.lang.NoSuchMethodError: org.springframework.aop.config.AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(Lorg/springframework/beans/factory/xml/ParserContext;Lorg/w3c/dom/Element;)V
	at org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser$AopAutoProxyConfigurer.configureAutoProxyCreator(AnnotationDrivenBeanDefinitionParser.java:109)
	at org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.parse(AnnotationDrivenBeanDefinitionParser.java:80)

Isso cheira a incompatibilidade. Algo na sua aplicação está com dependencia errada, por exemplo:

framework1-2.0.jar depende de framework2-3.2.jar
mas o que você tem é o framework2-2.7.jar

A incompatibilidade está no spring-aop aparentemente:

org.springframework.aop.config.AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(…);

Ele está procurando pelo metodo registerAutoProxyCreatorIfNecessary na classe AopNamespaceUtils, pois alguem esta chamando, mas não existe. Problema de incompatibilidade de versões.

Olá Guilherme consegui resolver a exception que postei e outras que vieram depois… agora ta dando essa que não estou conseguindo entender, parece que estou injetando o entityManagerFacoty no EntityManager, mas acho que não estou fazendo isso eu fiz o código da maneira que vc postou.

EVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
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.&lt;init&gt;(PersistenceAnnotationBeanPostProcessor.java:560)
	at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$1.doWith(PersistenceAnnotationBeanPostProcessor.java:359)
	at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:523)
	at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:500)
	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)

código da DAO

public class ProductDAO {
		
	private EntityManager _entityManager = null;
	
	@PersistenceContext
	private EntityManagerFactory _entityManagerFactory = null;
	
	
	public ProductDAO() {
	}
	
	@Transactional
	public void insert(Product product) {
		_entityManager = _entityManagerFactory.createEntityManager();
		_entityManager.getTransaction().begin();
		_entityManager.persist(product);
		_entityManager.getTransaction().commit();
	}

        // getters and setters

A annotation PersistenceContext vai no EntityManager e o próprio Spring injeta um EntityManager para você, esse é o erro. Ele está tentando injetar um entitymanager em um entitymanagerfactory.

Então ele já cria o entityManager pra mim automático, eu digo essa linha?:

_entityManager = _entityManagerFactory.createEntityManager();

pois agora aquele erro acabou mas tanto entityManager como o EntityManagerFactory estão dando NullPointerException


java.lang.NullPointerException
	at orm.dataaccess.dao.ProductDAO.insert(ProductDAO.java:28)
	at orm.controller.Teste.handleRequest(Teste.java:34)
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)

Faz assim, arranca esse EntityManagerFactory do seu codigo, deixa só o EntityManager, ele já vai vir com um instancia setada pelo Spring.

é tirei, mas o NullPointer continua, parece que ele nao fez a injeção.

SEVERE: Servlet.service() for servlet jpa threw exception
java.lang.NullPointerException
	at orm.dataaccess.dao.ProductDAO.insert(ProductDAO.java:24)
	at orm.controller.Teste.handleRequest(Teste.java:34)
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)

ProductDAO

public class ProductDAO {
	
	@PersistenceContext
	private EntityManager _entityManager = null;
	
	public ProductDAO() {
	}
	
	@Transactional
	public void insert(Product product) {
		_entityManager.getTransaction().begin();
		_entityManager.persist(product);
		_entityManager.getTransaction().commit();
	}

	public EntityManager getEntityManager() {
		return _entityManager;
	}

	public void setEntityManager(EntityManager entityManager) {
		_entityManager = entityManager;
	}

Estava dando uma pesquisada e vi essa parte da documentação falando de algumas configurações no Tomcat, será que isso pode influenciar?
http://static.springframework.org/spring/docs/2.5.x/reference/orm.html

Creio que o problema seja que você chamou seu EntityManager de _entityManager, então ele procura o setter set_entityManager() ou algo do tipo, tente mudar o nome da variavel apenas para entityManager e ele vai procurar pelo setEntityManager().

Eu configurei no eclipse que todos os atributos teriam underline, entao acho que quando ele encontra os metodos getters ou setters ele o desconsidera. Porém tirei pra ver e mesmo assim nao foi injetado. Ta bem complicado :frowning: