Injeção de controlador de transações não satisfeita no Spring MVC 4 + JPA 2 e Hibernate 5
Boa noite pessoas.
Depois de longos anos fora do mundo da programação Java, voltei a estudar com foco em um projeto de desenvolvimento web para o futuro.
Pois bem, estou tentando utilizar o Spring MVC 4, com JPA 2 e Hibernate 5 para controlar as transações com o banco de dados MySQL 8.
As conexões são todas realizadas, realizo consultas normalmente. O problema começa quando tento persistir, remover ou atualizar algum objeto, onde é necessário o controle de transação, e o Spring parece não estar fazendo essa injeção de dependência do EntityManager pra mim.
Segue os códigos:
dispatcher-servlet.xml
<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- CONFIGURAÇÃO PARA ACEITAR ANOTAÇÕES -->
<mvc:annotation-driven />
<context:component-scan base-package="base" />
<!-- CONFIGURAÇÃO DE BEAN PARA O INTERCEPTOR DE LOGIN -->
<!--<mvc:interceptors>
<bean class="base.interceptors.LoginInterceptor" />
</mvc:interceptors>-->
<!-- CONFIGURAÇÃO DE BEAN PARA RESOLUÇÃO DAS VIEWS -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
</beans>
applicationContext.xml
<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?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:p="http://www.springframework.org/schema/p"
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-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- ATIVANDO AS TRANSAÇÕES VIA ANOTAÇÃO PELOS CONTROLLERS -->
<tx:annotation-driven transaction-manager="txManager" />
<bean id="mySQLDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/teste?useSSL=false&serverTimezone=UTC"></property>
<property name="username" value="root"></property>
<property name="password" value="senha"></property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mySQLDataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
Classe Pessoa
package base.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "pessoas")
public class Pessoa {
@Id
@GeneratedValue
@Column(name = "id_pessoa", nullable = false)
private long id;
@Column(name = "nome_pessoa", nullable = false)
private String nome;
public Pessoa() {
}
public Pessoa(String nome) {
this.nome = nome;
}
public Pessoa(long id, String nome) {
this.id = id;
this.nome = nome;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
Classe JPAPessoaDAO
package base.hibernate;
import base.dao.interfaces.PessoaDAO;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import base.models.Pessoa;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceProperty;
import org.springframework.stereotype.Repository;
/*
A ANOTAÇÃO @REPOSITORY É UTILIZADA PARA A RESOLUÇÃO DE DEPENDÊNCIA DO DAO
*/
@Repository
public class JPAPessoaDAO implements PessoaDAO {
/*
Um PersistenceContext (Contexto Persistente) é um local onde ficam armazenados os objetos
(entidades) que estão sendo manipulados pelo EntityManager corrente
*/
@PersistenceContext
EntityManager manager;
@Override
public void inserirPessoa(Pessoa pessoa) {
manager.persist(pessoa);
}
@Override
public Pessoa buscarPessoa(long id) {
Pessoa pessoa = manager.find(Pessoa.class, id);
return pessoa;
}
@Override
public void removerPessoa(long id) {
Pessoa pessoa = manager.find(Pessoa.class, id);
manager.remove(pessoa);
}
@Override
public void atualizarPessoa(Pessoa pessoa) {
manager.merge(pessoa);
}
@Override
public List<Pessoa> listar() {
List<Pessoa> listaPessoas = manager
.createQuery("select p from Pessoa as p")
.getResultList();
return listaPessoas;
}
@Override
public List<Pessoa> listarPorID(long id) {
Query query = manager
.createQuery("select p from Pessoa as p where p.id = : paramID");
query.setParameter("paramID", id);
List<Pessoa> listaPessoas = query.getResultList();
return listaPessoas;
}
@Override
public EntityManager getEntityManager() {
return manager;
}
/*public static void main(String[] args) {
//JPAPessoaDAO pessoaDAO = new JPAPessoaDAO();
// INSERT
//Pessoa pessoa = new Pessoa("VALMORPE");
//pessoaDAO.inserirPessoa(pessoa);
// SELECT
//Pessoa pessoa = pessoaDAO.buscarPessoa(4L);
//System.out.println("Pessoa
Não gera erro algum, apenas me parece que não cria o objeto para gerenciar as transações via Injeção de Dependência do Spring.
Realizo consultas normalmente, já que para isso não necessitamos de um EntityManager.getTransaction.begin e commit, por exemplo. Mas nos métodos de inserir, atualizar e remover, simplesmente não faz nada no banco.
Alguma alma bondosa poderia ler todo o código e tentar me ajudar? Estou empacado nisso desde quinta-feira, dia 28 de julho. Já pesquisei no google, vi dezenas de outros exemplos, e até agora não encontrei erro algum.
Agradeço demais quem puder ajudar.
Abraços.
Depois de longos anos fora do mundo da programação Java, voltei a estudar com foco em um projeto de desenvolvimento web para o futuro.
Pois bem, estou tentando utilizar o Spring MVC 4, com JPA 2 e Hibernate 5 para controlar as transações com o banco de dados MySQL 8.
As conexões são todas realizadas, realizo consultas normalmente. O problema começa quando tento persistir, remover ou atualizar algum objeto, onde é necessário o controle de transação, e o Spring parece não estar fazendo essa injeção de dependência do EntityManager pra mim.
Segue os códigos:
dispatcher-servlet.xml
<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- CONFIGURAÇÃO PARA ACEITAR ANOTAÇÕES -->
<mvc:annotation-driven />
<context:component-scan base-package="base" />
<!-- CONFIGURAÇÃO DE BEAN PARA O INTERCEPTOR DE LOGIN -->
<!--<mvc:interceptors>
<bean class="base.interceptors.LoginInterceptor" />
</mvc:interceptors>-->
<!-- CONFIGURAÇÃO DE BEAN PARA RESOLUÇÃO DAS VIEWS -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
</beans>
applicationContext.xml
<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?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:p="http://www.springframework.org/schema/p"
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-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- ATIVANDO AS TRANSAÇÕES VIA ANOTAÇÃO PELOS CONTROLLERS -->
<tx:annotation-driven transaction-manager="txManager" />
<bean id="mySQLDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/teste?useSSL=false&serverTimezone=UTC"></property>
<property name="username" value="root"></property>
<property name="password" value="senha"></property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mySQLDataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
Classe Pessoa
package base.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "pessoas")
public class Pessoa {
@Id
@GeneratedValue
@Column(name = "id_pessoa", nullable = false)
private long id;
@Column(name = "nome_pessoa", nullable = false)
private String nome;
public Pessoa() {
}
public Pessoa(String nome) {
this.nome = nome;
}
public Pessoa(long id, String nome) {
this.id = id;
this.nome = nome;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
Classe JPAPessoaDAO
package base.hibernate;
import base.dao.interfaces.PessoaDAO;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import base.models.Pessoa;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceProperty;
import org.springframework.stereotype.Repository;
/*
A ANOTAÇÃO @REPOSITORY É UTILIZADA PARA A RESOLUÇÃO DE DEPENDÊNCIA DO DAO
*/
@Repository
public class JPAPessoaDAO implements PessoaDAO {
/*
Um PersistenceContext (Contexto Persistente) é um local onde ficam armazenados os objetos
(entidades) que estão sendo manipulados pelo EntityManager corrente
*/
@PersistenceContext
EntityManager manager;
@Override
public void inserirPessoa(Pessoa pessoa) {
manager.persist(pessoa);
}
@Override
public Pessoa buscarPessoa(long id) {
Pessoa pessoa = manager.find(Pessoa.class, id);
return pessoa;
}
@Override
public void removerPessoa(long id) {
Pessoa pessoa = manager.find(Pessoa.class, id);
manager.remove(pessoa);
}
@Override
public void atualizarPessoa(Pessoa pessoa) {
manager.merge(pessoa);
}
@Override
public List<Pessoa> listar() {
List<Pessoa> listaPessoas = manager
.createQuery("select p from Pessoa as p")
.getResultList();
return listaPessoas;
}
@Override
public List<Pessoa> listarPorID(long id) {
Query query = manager
.createQuery("select p from Pessoa as p where p.id = : paramID");
query.setParameter("paramID", id);
List<Pessoa> listaPessoas = query.getResultList();
return listaPessoas;
}
@Override
public EntityManager getEntityManager() {
return manager;
}
/*public static void main(String[] args) {
//JPAPessoaDAO pessoaDAO = new JPAPessoaDAO();
// INSERT
//Pessoa pessoa = new Pessoa("VALMORPE");
//pessoaDAO.inserirPessoa(pessoa);
// SELECT
//Pessoa pessoa = pessoaDAO.buscarPessoa(4L);
//System.out.println("Pessoa
Não gera erro algum, apenas me parece que não cria o objeto para gerenciar as transações via Injeção de Dependência do Spring.
Realizo consultas normalmente, já que para isso não necessitamos de um EntityManager.getTransaction.begin e commit, por exemplo. Mas nos métodos de inserir, atualizar e remover, simplesmente não faz nada no banco.
Alguma alma bondosa poderia ler todo o código e tentar me ajudar? Estou empacado nisso desde quinta-feira, dia 28 de julho. Já pesquisei no google, vi dezenas de outros exemplos, e até agora não encontrei erro algum.
Agradeço demais quem puder ajudar.
Abraços.
Alex Phill
Curtidas 0