Bom dia, estou tento problema ao tentar fazer qualquer coisa com o BANCO DE DADOS, com o projeto já no ar:
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute statement
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute statement
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1187)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
com.sun.proxy.$Proxy36.persist(Unknown Source)
br.com.casadocodigo.dao.ProdutoDao.grava(ProdutoDao.java:25)
br.com.casadocodigo.dao.ProdutoDao$$FastClassBySpringCGLIB$$701340e8.invoke(<generated>)
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
br.com.casadocodigo.dao.ProdutoDao$$EnhancerBySpringCGLIB$$c1afaa9a.grava(<generated>)
br.com.casadocodigo.Controller.ProdutosController.cadastraProdutos(ProdutosController.java:70)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause
org.hibernate.exception.SQLGrammarException: could not execute statement
org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:123)
org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3032)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3556)
org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:97)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:480)
org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:191)
org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:175)
org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:210)
org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:324)
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:807)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:780)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:785)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
com.sun.proxy.$Proxy36.persist(Unknown Source)
br.com.casadocodigo.dao.ProdutoDao.grava(ProdutoDao.java:25)
br.com.casadocodigo.dao.ProdutoDao$$FastClassBySpringCGLIB$$701340e8.invoke(<generated>)
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
br.com.casadocodigo.dao.ProdutoDao$$EnhancerBySpringCGLIB$$c1afaa9a.grava(<generated>)
br.com.casadocodigo.Controller.ProdutosController.cadastraProdutos(ProdutosController.java:70)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause
org.postgresql.util.PSQLException: ERROR: relation "produto" does not exist
Position: 13
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270)
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998)
org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:570)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:420)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:366)
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187)
org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3032)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3556)
org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:97)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:480)
org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:191)
org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:175)
org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:210)
org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:324)
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:807)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:780)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:785)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
com.sun.proxy.$Proxy36.persist(Unknown Source)
br.com.casadocodigo.dao.ProdutoDao.grava(ProdutoDao.java:25)
br.com.casadocodigo.dao.ProdutoDao$$FastClassBySpringCGLIB$$701340e8.invoke(<generated>)
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
br.com.casadocodigo.dao.ProdutoDao$$EnhancerBySpringCGLIB$$c1afaa9a.grava(<generated>)
br.com.casadocodigo.Controller.ProdutosController.cadastraProdutos(ProdutosController.java:70)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
-- CLASSE PRODUTO:
package br.com.casadocodigo.Model;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.format.annotation.DateTimeFormat;
@Entity // JPA/HIBERNATE - Como aqui está utilizando o MAVEN para tratar as dependências, é preciso colocar no POM.XML a dependência do Hibernate e JPA (para o funcionamento do @Entity)
public class Produto implements Serializable {
private static final long serialVersionUID = 1L;
@Id // Chave primária
@GeneratedValue(strategy=GenerationType.IDENTITY) // Gera automáticamente o valor do ID
private Long id;
private String titulo;
@Lob // @Lob = Guarda o conteúdo como byte no DB
@Column(length = 10000) // @Column = Indica o tamanho de caracteres que podem ser guardados nesse atributo no DB, e a referência.
private String descricao;
private int paginas;
private String sumarioPath; // Como será guardado o ARQUIVO ANEXADO no DB ? irá apenas guardar o "caminho" do arquivo
@Temporal(TemporalType.DATE) // JPA/HIBERNATE - Como cada DB tem seu próprio meio de gravar a data, com o @Temporal podemos indicar se desejamos gravar apenas a DATA, hora, ou ambos(TIMESTAMP)
@DateTimeFormat // Para não precisar especificar o "pattern=dd/mm/yyyy" em toda @DateTimeFormat, é criado uma configuração que trata isso como padrão, em "AppWebConfiguration"
private Calendar dataLancamento;
@ElementCollection // Utilizado para = RELACIONAMENTO COM "CHAVE PRIMÁRIA" E ATRIBUTO COM A ANNOTATION (@ElementCollection)] (Criará uma tabela com CHAVE PRIMARIA e todos os dados do OBJECT passado).
private List<Preco> precos;
// IRÁ BUSCAR O VALOR CORRESPONDENTE AO TipoPreco passado
public BigDecimal precoPara(TipoPreco tipo) {
// VERIFICA DENTRO DO PRODUTO ENTRE SEUS "Preco" qual o valor que irá retornar de acordo com o TipoPrecp passado
for (Preco preco : precos) {
if(preco.getTipo().equals(tipo)){
return preco.getValor();
}
}
// CASO NÃO DESEJE FAZER NA MÃO, PODE UTILIZAR UM "LAMBDA JAVA 8" PARA MESMA COISA ACIMA
// return precos.stream().filter(preco -> preco.getTipo().equals(tipo))
// .findFirst().get().getValor();
return null;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public int getPaginas() {
return paginas;
}
public void setPaginas(int paginas) {
this.paginas = paginas;
}
public List<Preco> getPrecos() {
return precos;
}
public void setPrecos(List<Preco> precos) {
this.precos = precos;
}
public Calendar getDataLancamento() {
return dataLancamento;
}
public void setDataLancamento(Calendar dataLancamento) {
this.dataLancamento = dataLancamento;
}
public String getSumarioPath() {
return sumarioPath;
}
public void setSumarioPath(String sumarioPath) {
this.sumarioPath = sumarioPath;
}
// LEMBRANDO: toString é utilizando quando tenta imprimir o OBJECT (CTRL + 3 + toString já gera)
@Override
public String toString() {
return "Produto [titulo=" + titulo + ", descricao=" + descricao + ", paginas=" + paginas + "]";
}
/*
* CRIADO PARA QUE NO "ContainsKey" do MAP criado em "CarrinhoCompas", não verifique se os
* OBJECTs do ITEM passado são iguais, e sim comparar os IDs de cada OBJECT passado
*
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Produto other = (Produto) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
--- PRODUTO CONTROLLER
package br.com.casadocodigo.Controller;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import br.com.casadocodigo.Model.Produto;
import br.com.casadocodigo.Model.TipoPreco;
import br.com.casadocodigo.dao.ProdutoDao;
import br.com.casadocodigo.infra.FileSaver;
import br.com.casadocodigo.validation.ProdutoValidation;
@Controller
@RequestMapping("/produtos") // Colocando RequestMapping na CLASS irá indicar que todos os RequestMapping dos métodos terão o caminho "produtos". (Assim não precisando repetir em cada método por exemplo (/produtos/lista), ficando apenas (/lista)
@Scope(value=WebApplicationContext.SCOPE_REQUEST) // OLHAR INFO (BEAN/SCOPE) = Aqui diz que cada usuário que faça uma REQUISIÇÃO que utilize essa classe, irá instânciar essa classe para cada usuário. (Por padrão seria utilizado essa mesma classe com a mesma requisição para todos os usuários)
public class ProdutosController {
@Autowired // Lembrando = Colocando para o Spring instânciar a "classe Dao" o DAO precisa ser @Repository
ProdutoDao produtoDao = new ProdutoDao();
@Autowired // O Spring que irá instãnciar essa classe para ser utilizada nesse CONTROLLER (Lembrando que como fileserver não é um DAO, em vez de usar o @Repository, foi posto o @Component)
private FileSaver filesaver;
@InitBinder // Fazendo o spring reconhecer o nosso validador
public void initBinder(WebDataBinder binder){
binder.addValidators(new ProdutoValidation()); // Pedindo para o spring framework para adicionar esse validador na lista de validadores. (Vai buscar o método herdado validate)
}
@RequestMapping(value="/form")
public ModelAndView form(Produto produto){ // Aqui o SPRING já fará um BINDING ao entrar na tela FORM, e deixara até o fim da requisição, e quando chamar o gravar, já terá o OBJETO com BIND
ModelAndView mv = new ModelAndView("produtos/formulario"); // Contém o caminho de redirecionamento da VIEW
mv.addObject("tipos",TipoPreco.values()); // TipoPreco.values()(Enum.values) = Pega um array com todos os dados do Enum.
return mv;
}
// CADASTRO PRODUTO
@RequestMapping(method=RequestMethod.POST) // RequestMethod = O modo que a requisição irá para o método. (indicando ao Spring MVC que esse mapeamento será chamado apenas se o método de requisição do HTTP for do tipo mencionado)
public ModelAndView cadastraProdutos(MultipartFile sumario, @Valid Produto produto,
BindingResult result, RedirectAttributes attributes){
// MultipartFile = O Spring enviará(BIND) nosso arquivo para o ProdutosController como um objeto do tipo MultipartFile
if(result.hasErrors()){ // Verifica se aconteceu algum erro no Validation
return form(produto); // Posso chamar o método como return pois ele returna o mesmo tipo que essa classe.
}
if (sumario != null && !sumario.getOriginalFilename().isEmpty()) {
String path = filesaver.write("arquivos-sumario", sumario); // Vai retornar só uma parte do caminho referente a pasta passada, para apenas guardar no DB("NomeDaPasta", fileRecebidoDaView)
produto.setSumarioPath(path); // Injeta no produto para guardar no banco de dados o caminho
}
produtoDao.grava(produto);
ModelAndView mv = new ModelAndView("redirect:produtos/form");
attributes.addFlashAttribute("sucesso", "Produto cadastrado com sucesso!"); // Envia um object que será temporário até o fim da próxima requisição
return mv; // Dicas IMP: Sempre tente fazer um REDIRECT/FOWARD após um POST (pois o post é onde está sendo tratado seus dados passados)
}
// BUSCA PRODUTOS
@RequestMapping(value="/lista" , method=RequestMethod.GET) // O modo que a requisição irá para o método.
public ModelAndView buscaProdutos(){
ModelAndView mv = new ModelAndView("produtos/lista");
List<Produto> produtos = produtoDao.lista();
mv.addObject("produtos", produtos);
return mv;
}
// DETALHE PRODUTO
@RequestMapping(value="/detalhe/{id}") // 1.1 URL AMIGÁVEL = Em vez de aparecer na URL de modo GET o parâmetro (ex: detalhe?id=5), aqui irá aprecer apenas (detalhe/5), mas é preciso fazer a ligação entre esse {id} e o argumento recebido por esse método, abaixo:
public ModelAndView detalhe(@PathVariable("id") Long id){ // 1.2 LIGAÇÃO PARA A URL AMIGÁVEL = @PathVariable("Passar o nome do que está no RequestMapping {id}"), e assim fazendo com que esse "Long id" seja passado no {id} do "RequestMapping"
ModelAndView mv = new ModelAndView("produtos/detalhe");
Produto produto = produtoDao.find(id);
mv.addObject("produto",produto);
return mv;
}
}
JPAPRODUCTION
package br.com.casadocodigo.conf;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
@Profile("prod")
public class JPAProductionConfiguration {
/*
* 1> CLASSE CRIADA PARA SEPARAR O DRIVER UTILIZADO EM "DESENVOLVIMENTO("dev")" E "PRODUÇÃO("prod")"
* 2> MUDANDO OS DADOS PARA QUE O BANCO SE RELACIONE COM "PostGre"
*
* * Mundar o DIALECT
* * Fazer o HEROKU(Site de Hospedagem) mandar as informações de URL,LOGIN e SENHA
*
*/
// UTILIZADO PARA PODER PEGAR A "VARIAVEL AMBIENTE" DO HEROKU
@Autowired
private Environment environment;
@Bean
private Properties additionalProperties(){
// CONFIGURANDO O DIALETO QUE O HIBERNATE IRÁ "CONVERSAR" COM O DB
Properties props = new Properties();
props.getProperty("hibernate.dialect","org.hibernate.dialect.PostgreSQLDialect"); // Dialeto de entendimento do BANCO DE DADOS UTILIZADO
props.setProperty("hibernate.show_sql", "true"); // Cria a permissão para poder ver o próprio SQL gerado pelo HIBERNATE
props.setProperty("hibernate.hbm2ddl.auto", "update"); // Para que toda vez que mudar as classes MODELOS já faça o UPDATE(Sincronização) com o DB
return props;
}
@Bean
private DataSource dataSource() throws URISyntaxException{
// COLOCANDO O DRIVER UTILIZADO E (LOGIN/SENHA)
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.postgresql.Driver"); // Qual tipo de BANCO que irá usar para essa conexão
// O HEROKU disponibiliza uma "VARIÁVEL AMBIENTE" que contém esses dados, para ser passado a nossas conf.
URI dbUrl = new URI(environment.getProperty("DATABASE_URL")); // DATABASE_URL é a variável que o HEROKU nos disponibiliza
// Fazer o HEROKU(Site de Hospedagem) mandar as informações de URL,LOGIN e SENHA
// SÓ QUE O DATABASE TRAZIDO VEM EM UM PADRÃO: usuario:senha@hots:port/path
dataSource.setUsername(dbUrl.getUserInfo().split(":")[0]); // Como o usuário e senha estão "grudados" o split divide a STRING em 2 e a separação é o ":", existindo agora String[0] (Lado esquerdo) e String[1](Lado direito)
dataSource.setPassword(dbUrl.getUserInfo().split(":")[1]);
dataSource.setUrl("jdbc:postgresql://"+ dbUrl.getHost() + ":" + dbUrl.getPort() + dbUrl.getPath()); // Caminho da forma e onde o banco será criado.
/* |_____________| |_____________| |_____________|
* | | |
* | | |-> Contém os caminhos no SITE (ex: produtos/form)
* | |-> Heroku já entrega a "porta padrão" utilizada pelo "PostGre"
* |-> Pega o endereço do site (nesse caso gigormv)
*/
return dataSource;
}
}
pom.XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.W202SpringMvc2WEB</groupId>
<artifactId>W202SpringMvc2WEB</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<finalName>W202SpringMvc2WEB</finalName>
<!-- SESSÃO DE PUGLINS (Precisa estar dentro de "build/plugins" -->
<plugins>
<!-- Necessário o Plugin do MAVEN -->
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<!-- Adição de um plugin de um projeto Maven configurado que irá fazer
com que a nossa aplicação seja executada como um jar. Diferente do
que acontece quando a aplicação é executada dentro do Tomcat. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>copy</goal></goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.github.jsimone</groupId>
<artifactId>webapp-runner</artifactId>
<version>7.0.57.2</version>
<destFileName>webapp-runner.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- ABAIXO FICA AS DEPÊNDENCIAS PARA O MAVEN APLICAR NO PROJETO -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId> <!-- Pegando a API da SPRINGMVC -->
<artifactId>spring-webmvc</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId> <!-- Pegando a API da APACHE -->
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.30</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId> <!-- Pegando a API da JSTL -->
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId> <!-- Pegando a API da SERVLET -->
</exclusion>
</exclusions>
</dependency>
<!-- Parte do Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.6.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<scope>runtime</scope>
</dependency>
<!-- vamos declarar algumas novas dependências. Entre elas estão a JPA, o Hibernate, O SpringORM e o Driver MySQL. -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<!-- <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.15</version>
</dependency>
-->
<!-- Utilizando o HSQLDB em vez do MYSQL -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.4.0</version>
</dependency>
<!-- Utilizando o POSTGRE para a publicação no HEROKU (Que só aceita DB PostGre) -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1201-jdbc41</version>
</dependency>
<!-- Referente ao Bean Validation (Spring) -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
<!-- O Spring se encarregando de fazer a conversão do objeto para JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.1</version>
</dependency>
</dependencies>
</project>
---Algum porquê disso ?