Issue
i know this question is recurring, but i haven't found the solution yet. My Web Application with Hibernate returns this error in query:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Prodotti is not mapped [SELECT p FROM Prodotti p]
This is my pom configuration:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.30.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.2.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
This is my config class:
package it.prova.web.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
import it.prova.web.dao.ProdottoService;
import it.prova.web.dao.ProdottoServiceImpl;
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "it.prova.web.controller")
@PropertySource("classpath:my-catalogue.properties")
@EnableTransactionManagement
public class MyCatalogueConfig {
@Autowired
private Environment env;
@Bean
public FreeMarkerViewResolver getFreeMarkerResolver() {
FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
resolver.setPrefix("");
resolver.setSuffix(".ftl");
return resolver;
}
@Bean
public FreeMarkerConfigurer getFreeMarkerConfigurer() {
FreeMarkerConfigurer config = new FreeMarkerConfigurer();
config.setTemplateLoaderPath("/WEB-INF/view/");
return config;
}
@Bean
public DataSource getDataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(env.getRequiredProperty("my-catalogue.db.driver"));
ds.setUrl(env.getRequiredProperty("my-catalogue.db.url"));
ds.setUsername(env.getRequiredProperty("my-catalogue.db.username"));
ds.setPassword(env.getRequiredProperty("my-catalogue.db.password"));
return ds;
}
@Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactory() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.MYSQL);
adapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
bean.setDataSource(getDataSource());
bean.setJpaVendorAdapter(adapter);
bean.setPackagesToScan(getClass().getPackage().getName());
return bean;
}
@Bean
public PlatformTransactionManager getTransactionManager() {
return new JpaTransactionManager(getEntityManagerFactory().getObject());
}
@Bean
public ProdottoService getProdottoService() {
return new ProdottoServiceImpl();
}
}
This is my controller:
package it.prova.web.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import it.prova.web.dao.ProdottoService;
import it.prova.web.model.Prodotto;
@Controller
@RequestMapping("/")
public class ProdottoController {
@Autowired
private ProdottoService service;
@GetMapping("/")
public ModelAndView index() {
return new ModelAndView("index", "listaProdotti", service.getAll());
}
@PostMapping("/add")
public String add(@ModelAttribute("datiProdotto") Prodotto p) {
service.add(p);
return "redirect:/";
}
@PostMapping("/update")
public String update(@ModelAttribute("datiProdotto") Prodotto p) {
service.update(p);
return "redirect:/";
}
@GetMapping("/delete")
public String delete(@RequestParam("id") String idProdotto) {
if(idProdotto != null)
service.delete(Integer.parseInt(idProdotto));
return "redirect:/";
}
}
This is my service implementation (avoid the interface...):
package it.prova.web.dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import it.prova.web.model.Prodotto;
public class ProdottoServiceImpl implements ProdottoService {
@PersistenceContext
private EntityManager em;
@Override
@Transactional
public void add(Prodotto p) {
em.persist(p);
}
@Override
@Transactional
public void update(Prodotto p) {
em.merge(p);
}
@Override
@Transactional
public void delete(int id) {
em.remove(getById(id));
}
@Override
public Prodotto getById(int id) {
return em.find(Prodotto.class, id);
}
@Override
public List<Prodotto> getAll() {
Query q = em.createQuery("SELECT p FROM Prodotto p");
return q.getResultList();
}
}
and finally the model:
package it.prova.web.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "prodotti")
public class Prodotto {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "descrizione")
private String descrizione;
@Column(name = "prezzo")
private Integer prezzo;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDescrizione() {
return descrizione;
}
public void setDescrizione(String descrizione) {
this.descrizione = descrizione;
}
public Integer getPrezzo() {
return prezzo;
}
public void setPrezzo(Integer prezzo) {
this.prezzo = prezzo;
}
public Prodotto(String descrizione, Integer prezzo) {
super();
this.descrizione = descrizione;
this.prezzo = prezzo;
}
public Prodotto() {
super();
}
}
I don't understand: Prodotto is mapped... Please help me.
Solution
After reading your configurations, you have misconfigured your EntityManager. You have this:
@Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactory() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.MYSQL);
adapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
bean.setDataSource(getDataSource());
bean.setJpaVendorAdapter(adapter);
bean.setPackagesToScan(getClass().getPackage().getName()); // This line scan the package of your configuration class not the package containing your entities
return bean;
}
You should have something like:
@Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactory() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.MYSQL);
adapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
bean.setDataSource(getDataSource());
bean.setJpaVendorAdapter(adapter);
bean.setPackagesToScan(Prodotto.class.getPackageName);
return bean;
}
Also, your configurations could be improved.
Answered By - akuma8
Answer Checked By - Candace Johnson (JavaFixing Volunteer)