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

为什么Wildfly应用重启后Hibernate查询不到之前持久化的数据?

问题现象

我正在学习JPA、EJB、Servlet相关技术,大部分功能运行正常,但无论怎么操作,我都无法在Wildfly服务器重启应用后,让Hibernate查询到我之前持久化的任何数据。
这个问题全程没有任何错误提示,日志中也没有相关输出,而且我调用实体管理器的.contains方法检查对象,返回结果为true,说明对象确实存在于实体管理器中。

已尝试的排查手段

  • 手动添加flush()调用
  • 将实体类显式添加到persistence.xml中(按规则框架应该可以自动扫描到)
  • 修改javax.persistence.schema-generation.database.action配置为create、drop-and-create、drop、none,均没有效果

相关配置与代码

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="EJBColis">
        <class>jpa.Colis</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="javax.persistence.schema-generation.database.action" value="create"/>
        </properties>
    </persistence-unit>
</persistence>

EJBColis.java

package ejb;
import java.util.LinkedList;
import java.util.List;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import jpa.Colis;
import jpa.Mesure;
import jpa.Position;

@Stateless
@LocalBean
public class EJBColis {
    @PersistenceContext
    private EntityManager em;
    /**
     * 无参构造函数(必填)
     */
    public EJBColis() {
    }
    public Colis addColis(double poid,double valeur,String origin,String destination,Position p ) {
        Colis m = new Colis(poid, valeur, origin, destination, p);
        em.persist(m);
        em.flush();
        em.refresh(m);
        return m;
    }
    public Colis findColis(long id) {
        Colis m = em.find(Colis.class, id);
        return m;
    }
    public Position changePosition(long ColisId,double longitude,double lat,String origin,String destination) {
        Position m = new Position(longitude,lat, origin, destination);
        Colis c = findColis(ColisId);
        c.setPosition(m);
        em.persist(c);
        em.flush();
        return m;
    }
    public Position findPosition(long id) {
        Position m = em.find(Position.class, id);
        return m;
    }
}

addColisServlet.java

package servlet;
import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ejb.EJBColis;
import jpa.Colis;
import jpa.Mesure;
import jpa.Position;

/**
 * AddColisServlet实现类
 */
@WebServlet("/AddColisServlet")
public class AddColisServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    // EJB引用注入
    @EJB
    private EJBColis ejb;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public AddColisServlet() {
        super();
    }
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        double Poid = Double.parseDouble(request.getParameter("poid"));
        double valeur = Double.parseDouble(request.getParameter("valeur")) ;
        String origine = request.getParameter("origine");
        String destination = request.getParameter("destination");
        Position position = null;
        Colis m = ejb.addColis(Poid, valeur, origine, destination, position);               
        // 将包裹信息存入请求
        request.setAttribute("Colis",m);
        // 转发到展示JSP页面
        request.getRequestDispatcher("/showColis.jsp").forward(request, response);
    }
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

调用addColisServlet的前端页面

<!DOCTYPE html>
<html>
<head>
    <meta charset="ISO-8859-1">
    <title>包裹管理</title>
    <link rel="stylesheet" type="text/css" href="css/base.css" >
</head>
<body>
<h1>包裹管理</h1>
    <h2>查询包裹物流:</h2>
    <form action="ShowColisServlet" method="post">
        ID : <input type="number" name="ID">
        <input type="submit" value="提交">
    </form>
    <h2>创建新包裹</h2>
    <form action="AddColisServlet" method="post">
        重量 : <input type="number" name="poid">
        价值 : <input type="number" name="valeur">
        始发地 : <input type="text" name="origine">
        目的地 : <input type="text" name="destination">
        <input type="submit" value="提交">
    </form>
    <h2>修改包裹位置:</h2>
    <form action="ModifColisServlet" method="post">
        ID : <input type="text" name="ID">
        纬度 : <input type="number" name="lat">
        经度 : <input type="number" name="long">
        当前位置 : <input type="text" name="emplacement">
        状态 : <input type="text" name="etat">
        <input type="submit" value="提交">
    </form>
</body>
</html>

解决方案

根因1:默认使用了Wildfly内存数据库

Wildfly默认集成的嵌入式H2数据库默认是内存存储模式,服务重启后所有内存数据会自动清空,你没有显式配置持久化数据源,所以写入的数据重启后自然丢失。

根因2:表生成策略配置错误

你当前persistence.xml中javax.persistence.schema-generation.database.action配置值为create,这个配置的含义是每次应用启动都会删除原有表、重新创建表结构,就算你用了持久化存储的数据库,启动后原有数据也会被清空。

修复步骤

  1. 修改表生成策略:开发阶段可以改成update(仅同步表结构变更,不会清空数据),生产环境必须改成none,示例配置:
<property name="javax.persistence.schema-generation.database.action" value="update"/>
  1. 配置持久化数据源:可以将H2改成文件存储模式,或者配置MySQL、PostgreSQL等独立数据库作为数据源,在persistence-unit节点中指定配置好的数据源JNDI名称即可,示例:
<persistence-unit name="EJBColis" transaction-type="JTA">
    <jta-data-source>java:/MySqlDS</jta-data-source>
    <!-- 其余原有配置保持不变 -->
</persistence-unit>
  1. 代码优化:更新包裹位置的changePosition方法中,查询出来的Colis已经是持久态对象,不需要重复调用persist,直接修改属性后flush即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:15:08