You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已解决:Java Hibernate QuerySyntaxException:类未映射问题

解决Hibernate QuerySyntaxException: Class is not mapped 错误

问题背景

作为Hibernate新手,开发宿舍管理桌面应用时,已创建并填充hostel_db MySQL数据库,尝试执行查询from Hostel时抛出QuerySyntaxException: Class is not mapped错误,数据库连接正常,但无法识别实体类。

错误根源

原ConnectionUtils类中,Hibernate配置仅加载了hibernate.cfg.xml,但未显式添加实体类到配置中,导致Hibernate无法映射实体与数据库表的关联。

修正后的ConnectionUtils类

public class ConnectionUtils {
    private static Map<String, String> databaseProperties = new HashMap<>();
    private static Configuration databaseConfiguration = new Configuration();
    private static final String dialect = "org.hibernate.dialect.MySQL5Dialect";
    private static final String url = "jdbc:mysql://localhost:3306/".concat(ConnectionData.getDbName());
    private static final String driver = "com.mysql.cj.jdbc.Driver";
    private static EntityManagerFactory emf;
    private static SessionFactory sessionFactory;

    public ConnectionUtils(){}

    public void setUpProperties() {
        propertiesSetup(ConnectionData.getUsr(), ConnectionData.getPsw());

        StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder().
                applySettings(databaseConfiguration.getProperties());

        emf = Persistence.createEntityManagerFactory(ConnectionData.getTablesPackage(), databaseProperties);
        sessionFactory = databaseConfiguration.buildSessionFactory(standardServiceRegistryBuilder.build());
    }

    public EntityManagerFactory getEntityManagerFactory() {
        return emf;
    }

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    private static void propertiesSetup(String username, String password) {
        // 加载hibernate.cfg.xml配置
        try {
            databaseConfiguration.configure().
                    setProperty("hibernate.connection.username", username).
                    setProperty("hibernate.connection.password", password);
        } catch (HibernateException e) {
            if (verifyHibernateConfigXml())
                throw new RuntimeException("hibernate.cfg.xml格式错误");
        }

        persistenceSetup(username, password);
    }

    private static boolean verifyHibernateConfigXml() {
        try {
            InputStream is = ConnectionUtils.class.getClassLoader().getResourceAsStream("hibernate.cfg.xml");
            return true;
        } catch (NullPointerException npe) {
            throw new RuntimeException("hibernate.cfg.xml不存在");
        }
    }

    private static void persistenceSetup(String username, String password) {
        // 自动扫描包下的实体类并添加到配置
        try {
            for (Class cls : getEntityClassesFromPackage(ConnectionData.getTablesPackage())) {
                databaseConfiguration.addAnnotatedClass(cls);
            }
        } catch (Exception ex) { 
            ex.printStackTrace(); 
        }

        // 设置数据库连接属性
        databaseProperties.put("hibernate.connection.driver_class", driver);
        databaseProperties.put("hibernate.connection.url", url);
        databaseProperties.put("hibernate.connection.autocommit", "false");
        databaseProperties.put("hibernate.connection.username", username);
        databaseProperties.put("hibernate.connection.password", password);
        databaseProperties.put("hibernate.dialect", dialect);
        databaseProperties.put("hibernate.connection.CharSet", "utf8");
        databaseProperties.put("hibernate.connection.characterEncoding", "utf8");
        databaseProperties.put("hibernate.connection.useUnicode", "true");
        databaseProperties.put("hibernate.show_sql", "true");
        databaseProperties.put("hibernate.hbm2ddl.auto", "update");
    }

    // 扫描指定包下的所有类
    private static List<Class<?>> getEntityClassesFromPackage(String packageName) throws ClassNotFoundException, URISyntaxException {
        List<String> classNames = getClassNamesFromPackage(packageName);
        List<Class<?>> classes = new ArrayList<Class<?>>();
        for (String className : classNames) {
            Class<?> cls = Class.forName(packageName + "." + className);
            // 筛选带有@Entity注解的类
            for (Annotation annotation : cls.getAnnotations()) {
                if (annotation instanceof javax.persistence.Entity) {
                    classes.add(cls);
                }
            }
        }
        return classes;
    }

    // 获取指定包下的所有类名
    private static ArrayList<String> getClassNamesFromPackage(String packageName) throws URISyntaxException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        ArrayList<String> names = new ArrayList<String>();

        packageName = packageName.replace(".", "/");
        URL packageURL = classLoader.getResource(packageName);

        URI uri = new URI(packageURL.toString());
        File folder = new File(uri.getPath());
        File[] files = folder.listFiles();
        for (File file: files) {
            String name = file.getName();
            name = name.substring(0, name.lastIndexOf('.'));  // 移除.class后缀
            names.add(name);
        }
        return names;
    }
}

额外说明

  1. MySQL驱动更新:将原驱动com.mysql.jdbc.Driver替换为com.mysql.cj.jdbc.Driver,适配新版MySQL驱动规范。
  2. 实体类自动扫描:新增包扫描逻辑,自动识别带有@Entity注解的实体类并添加到Hibernate配置,避免手动添加实体类的繁琐操作。
  3. Main类调用调整:原静态方法改为实例方法,调用方式需修改为:
public class Main {
    public static void main(String[] args) {
        ConnectionUtils connUtils = new ConnectionUtils();
        connUtils.setUpProperties();
        
        // 获取SessionFactory和EntityManager
        SessionFactory sessionFactory = connUtils.getSessionFactory();
        EntityManager em = connUtils.getEntityManagerFactory().createEntityManager();
        
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Query query = session.createQuery("from Hostel");
        List<?> list = query.getResultList();
        Hostel hostel = (Hostel) list.get(0);
        System.out.println("\nHostel: \n" + hostel);
        
        transaction.commit();
        session.close();
        em.close();
    }
}

内容的提问来源于stack exchange,提问作者Antonino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:20:37