Hibernate+Struts2报错:无法解析根实体LoginHibernate求助
我是Stack Overflow新手,用Hibernate和Struts2开发登录验证器时遇到以下错误:
java.lang.IllegalArgumentException: org.hibernate.query.sqm.UnknownEntityException: Could not resolve root entity 'LoginHibernate'
我已经尝试修改hibernate.cfg.xml并检查Oracle数据库,但问题仍未解决,恳请帮忙排查原因。
LoginAction类
package action; import javax.servlet.http.HttpSession; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; import dao.LoginDAOHibernate; import pojo.LoginHibernate; public class LoginAction extends ActionSupport { private String userName; private String password; public String execute() { String statusCode = ""; HttpSession session = ServletActionContext.getRequest().getSession(); System.out.println("execute() method called in LoginAction"); // Create a LoginInfo object with the provided username and password LoginHibernate loginInfo = new LoginHibernate(); loginInfo.setUserName(userName); loginInfo.setPassword(password); System.out.println("loginInfo called in LoginAction"); boolean isUserValid = LoginDAOHibernate.isUserValid(loginInfo); // Set loggedInUser attribute in session if user is valid if (isUserValid) { session.setAttribute("loggedInUser", userName); statusCode = "success"; } else { statusCode = "input"; } return statusCode; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
LoginDAOHibernate类
package dao; import org.hibernate.Session; import org.hibernate.query.Query; import dbutil.HibernateDBUtil; import jakarta.persistence.NoResultException; import jakarta.persistence.TypedQuery; import pojo.LoginHibernate; public class LoginDAOHibernate { public static boolean isUserValid(LoginHibernate userDetails) { boolean validStatus = false; Session session = null; try { session = HibernateDBUtil.getSessionFactory().openSession(); // Create HQL query to check user credentials String hql = "FROM LoginHibernate WHERE userName = :userName AND password = :password"; System.out.println("Called isUserValid() in LoginDaoHibernate"); Query<LoginHibernate> query = session.createQuery(hql, LoginHibernate.class); System.out.println("Called user Query"); query.setParameter("userName", userDetails.getUserName()); query.setParameter("password", userDetails.getPassword()); try { LoginHibernate user = query.getSingleResult(); if (user != null) { validStatus = true; System.out.println("TEST LOGINDAO"); } } catch (NoResultException e) { // No need to do anything here, as validStatus remains false } } catch (Exception e) { e.printStackTrace(); } finally { // Close the Hibernate Session if (session != null) { session.close(); } } return validStatus; } }
HibernateDBUtil类
package dbutil; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; public class HibernateDBUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder() .configure("hibernate.cfg.xml") // or "persistence.xml" if using JPA .build(); Metadata metadata = new MetadataSources(standardRegistry) .addAnnotatedClass(pojo.LoginHibernate.class) // Ensure this matches your package and class name .getMetadataBuilder() .build(); return metadata.getSessionFactoryBuilder().build(); } catch (Exception e) { e.printStackTrace(); return null; } } public static SessionFactory getSessionFactory() { return sessionFactory; } }
LoginHibernate实体类
package pojo; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "login_info") public class LoginHibernate { @Id @Column(name = "USER_NAME", nullable = false, unique = true) public String userName; @Column(name = "PASSWORD", nullable = false) public String password; // Default constructor (required by Hibernate) public LoginHibernate() { } // Constructor with fields public LoginHibernate(String userName, String password) { this.userName = userName; this.password = password; } // Getters and setters public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
排查方向:
统一JPA包导入:代码里同时出现了
javax.persistence.*(实体类)和jakarta.persistence.*(DAO类),Hibernate 6+使用Jakarta EE规范,Hibernate 5及以下使用Java EE的javax包,混用会导致实体无法被识别。要么全换成jakarta.persistence.*(对应Hibernate 6+),要么全用javax.persistence.*(对应Hibernate 5.x)。确认实体注册是否生效:
- 检查
HibernateDBUtil中addAnnotatedClass(pojo.LoginHibernate.class)的包路径和类名是否完全正确,有没有拼写错误。 - 或者直接在
hibernate.cfg.xml中添加实体映射配置:<mapping class="pojo.LoginHibernate"/>,两种方式选其一即可。 - 查看控制台输出的
buildSessionFactory()异常信息,确认SessionFactory是否成功初始化,如果初始化失败返回null,后续的Session操作必然报错。
- 检查
检查HQL语句的实体名:HQL中的实体名必须和实体类的类名完全一致(大小写敏感),如果实体类用了
@Entity(name="自定义名称"),那HQL里要使用这个自定义名称;当前没有设置name属性,用类名LoginHibernate是正确的,确保拼写无误。验证依赖版本兼容性:Struts2和Hibernate的版本要匹配,比如Struts2 6.x依赖Jakarta EE,必须搭配Hibernate 6.x;如果用Struts2 5.x,可以搭配Hibernate 5.x,避免版本不兼容导致的实体识别问题。
核对数据库表映射:Oracle数据库默认表名和列名是大写的,确认
@Table(name = "login_info")对应的数据库表实际是LOGIN_INFO,如果不一致,修改注解为@Table(name = "LOGIN_INFO");列名同理,确保@Column(name = "USER_NAME")和数据库列名一致。
内容的提问来源于stack exchange,提问作者Kenneth Igot

