Hibernate table 查询中未映射错误

Hibernate table not mapped error in query

我知道这个问题反复出现,但我还没有找到解决方案。我的 Hibernate Web 应用程序 returns 查询中出现此错误:

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]

这是我的 pom 配置:

<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>

这是我的配置 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();
    }
}

这是我的控制器:

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:/";
    }
}

这是我的服务实现(避免接口...):

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();
    }

}

最后是模型:

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();
    }
    
}

我不明白:Prodotto被映射...请帮助我。

阅读您的配置后,您错误地配置了 EntityManager。你有这个:

    @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;
    }

你应该有这样的东西:

    @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;
    }

此外,您的配置还可以改进。

另外,如果您的数据库中有多个表,则也可能是由于其中的映射(OnetoMany 和 ManyToOne ...)不正确。您也可以查看一下。