WebServlet中init(ServletConfig config)使用EntityManager初始化数据库失败
Hey Alina, let's break down what's happening and fix this problem step by step:
First, understand those log messages
The repeated visiting unvisited references lines are debug-level logs from Hibernate (assuming you're using JPA with Hibernate as the provider) — it's just Hibernate scanning your entity classes to map database tables. The logout successful message is a hint that your EntityManagerFactory might be getting closed prematurely, which is probably why your initialization isn't working as expected.
1. Stop overriding init(ServletConfig config) — use init() instead
When you override init(ServletConfig), you must call super.init(config) to let the servlet container properly initialize the servlet context and other core resources. If you skip this, you'll run into issues accessing persistence resources. Instead, use the no-arg init() method which handles this automatically:
@WebServlet("/YourRecipeServlet") public class RecipeServlet extends HttpServlet { private EntityManager em; @Override public void init() throws ServletException { // Replace "YourPersistenceUnit" with the name from your persistence.xml EntityManagerFactory emf = Persistence.createEntityManagerFactory("YourPersistenceUnit"); em = emf.createEntityManager(); } // Your doGet/doPost methods here... @Override public void destroy() { // Clean up EntityManager when servlet is destroyed if (em != null && em.isOpen()) { em.close(); } } }
2. Validate your persistence.xml configuration
Double-check these key settings in src/main/resources/META-INF/persistence.xml:
- Ensure the
<persistence-unit>hastransaction-type="RESOURCE_LOCAL"(since you're using it in a Servlet without container-managed transactions) - Verify your database URL, driver class, username, and password are correct
- Make sure your entity classes are being scanned: either list them explicitly with
<class>tags, or set<exclude-unlisted-classes>false</exclude-unlisted-classes>
3. Reduce noisy debug logs (optional)
If those visiting unvisited references lines are cluttering your logs, you can lower Hibernate's log level in GlassFish:
- Open NetBeans' Services tab, expand Servers, right-click your GlassFish instance, and select View Domain Admin Console
- Navigate to Configuration > Logger Settings
- In the Logger Name field, enter
org.hibernate, set the Level toINFO, and save the changes
4. Use a ServletContextListener for global EntityManagerFactory (best practice)
Creating an EntityManagerFactory in every servlet's init() is inefficient — it's meant to be a singleton for your entire app. Use a listener to initialize it once when the app starts:
@WebListener public class EMFInitializer implements ServletContextListener { private static EntityManagerFactory emf; @Override public void contextInitialized(ServletContextEvent event) { emf = Persistence.createEntityManagerFactory("YourPersistenceUnit"); event.getServletContext().setAttribute("emf", emf); } @Override public void contextDestroyed(ServletContextEvent event) { if (emf != null && emf.isOpen()) { emf.close(); } } public static EntityManagerFactory getEntityManagerFactory() { return emf; } }
Then in your servlet, fetch the factory from the context:
@Override public void init() throws ServletException { EntityManagerFactory emf = (EntityManagerFactory) getServletContext().getAttribute("emf"); em = emf.createEntityManager(); }
Give these steps a try — the most likely culprit is forgetting to call super.init(config) when overriding the parameterized init method, which breaks the servlet's resource access.
内容的提问来源于stack exchange,提问作者Alina

