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

REST API调用H2数据库查询返回空结果,main方法正常的问题修复

问题:REST API使用Hibernate查询H2数据库返回空列表,但main方法查询正常

我开发了一个使用Hibernate从H2数据库获取数据的REST API,已向数据库添加数据,但API中的查询返回空列表,而main方法中执行相同的查询却能返回正确数据,请问该如何解决此问题?


DroneResource.java

@Path("/drones")
public class DroneResource {

    @GET
    @Produces("application/json")
    public List<Employee> getEmployee() {
        EmployeeDAO dao = new EmployeeDAO();
         // 返回空列表
        List employees = dao.getEmployees();
        return employees;
    }

    public static void main(String[] args) {
        EmployeeDAO dao = new EmployeeDAO();
       // 从数据库返回正确数据
       List employees = dao.getEmployees(); 

    }
}

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory name="hibernateSessionFactory">
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:./h2db;AUTO_SERVER=TRUE</property>
        <property name="hibernate.connection.username">admin</property>
        <property name="hibernate.connection.password">admin</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
        <property name="hibernate.connection.server_timezone">UTC</property>

        <mapping class="com.gitlab.olorini.test.Employee"/>

    </session-factory>
</hibernate-configuration>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">
    <display-name>Drones manager</display-name>
    <servlet>
        <servlet-name>Example API</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>

        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.gitlab.olorini.web.services.endpoints</param-value>
        </init-param>

        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>Example API</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

数据库实体类 Employee.java

@Entity
public class Employee {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    @Column
    private String name;
    @Column
    private int age;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

}

DAO 相关代码

EmployeeDAO.java

public class EmployeeDAO {

   public List<Employee> getEmployees(){
        Session session = SessionUtil.getSession();
        Query query = session.createQuery("from Employee");
        List<Employee> employees =  query.list();
        session.close();
        return employees;
    }
}

SessionUtil.java

public class SessionUtil {

    private static SessionUtil instance=new SessionUtil();
    private SessionFactory sessionFactory;

    public static SessionUtil getInstance(){
        return instance;
    }

    private SessionUtil(){
        Configuration configuration = new Configuration();
        configuration.configure("hibernate.cfg.xml");

        sessionFactory = configuration.buildSessionFactory();
    }

    public static Session getSession(){
        Session session =  getInstance().sessionFactory.openSession();

        return session;
    }
}

build.gradle

plugins {
    id 'java'
    id 'war'
}

group 'com.github.olorini'
version '1.0-SNAPSHOT'

sourceCompatibility = '1.8'
project.webAppDirName = 'web'

repositories {
    mavenCentral()
    flatDir {
        dirs 'lib'
    }
}

dependencies {
    implementation 'log4j:log4j:1.2.17'
    implementation 'org.hibernate:hibernate-core:5.6.12.Final'
    implementation 'javax.validation:validation-api:2.0.1.Final'
    runtimeOnly 'com.h2database:h2:2.1.214'
    implementation 'com.sun.jersey:jersey-bundle:1.19.4'
    implementation 'com.sun.jersey:jersey-json:1.19.4'
    testImplementation 'junit:junit:4.13.2'
}

test {
    useJUnitPlatform()
}

排查与解决方法

1. 数据库路径不统一

Web应用和本地main方法的工作目录不同,导致各自访问的是不同的H2数据库文件。

  • 解决:把H2连接URL改成绝对路径,比如jdbc:h2:/Users/xxx/project/h2db;AUTO_SERVER=TRUE,确保Web容器和main方法访问同一个数据库文件。

2. 事务未正确处理

Hibernate在某些环境下,查询操作也需要显式开启事务才能获取数据。

  • 修改EmployeeDAO代码:
public List<Employee> getEmployees(){
    Session session = SessionUtil.getSession();
    List<Employee> employees = new ArrayList<>();
    try {
        session.beginTransaction();
        Query query = session.createQuery("from Employee");
        employees = query.list();
        session.getTransaction().commit();
    } catch (Exception e) {
        if (session.getTransaction().isActive()) {
            session.getTransaction().rollback();
        }
        e.printStackTrace();
    } finally {
        session.close();
    }
    return employees;
}

3. 实体类缺少无参构造函数

Hibernate和JSON序列化都要求实体类有无参构造函数,当前Employee类没有,可能导致数据无法正常实例化或序列化。

  • 给Employee添加无参构造:
@Entity
public class Employee {
    // 原有字段和方法
    public Employee() {} // 添加无参构造
}

4. H2自动服务器模式问题

AUTO_SERVER=TRUE在Web容器环境下可能存在连接冲突,导致无法正确读取数据。

  • 解决:启动独立的H2服务器,修改连接URL为jdbc:h2:tcp://localhost/./h2db,确保Web应用通过TCP连接访问同一个数据库。

5. 类路径下实体映射未被加载

检查Web应用中Hibernate是否能找到Employee类,确认hibernate.cfg.xml中的<mapping class="com.gitlab.olorini.test.Employee"/>路径正确,且实体类已被打包到WAR包中。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 03:01:25