使用Hibernate从数据库取数据时触发InvocationTargetException问题
问题解决:Unrecognized JPA persistence.xml XSD version : 3.0
核心错误原因
你使用的Hibernate版本不支持JPA 3.0规范,导致无法识别persistence.xml中指定的3.0版本XSD。
解决方案
方案1:降低JPA版本适配现有Hibernate
修改persistence.xml的头部声明,使用适配Hibernate 5.x系列的JPA 2.2版本XSD,同时补全完整的persistence-unit结构:
<?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="default" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <class>com.example.demo.ActorEntity</class> <class>com.example.demo.AddressEntity</class> ... <properties> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/Sakila"/> <property name="hibernate.connection.driver_class" value="com.mysql.cj.jdbc.Driver"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="ß§%Y-Sn_ß-DF/n-/%D5-m274-§_9s%"/> <!-- 必须添加MySQL方言配置,避免Hibernate自动检测出错 --> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/> </properties> </persistence-unit> </persistence>
方案2:升级Hibernate到支持JPA 3.0的版本
若要保留JPA 3.0规范,需将Hibernate升级到6.x版本(JPA 3.0对应Hibernate 6+),同时修正persistence.xml的头部命名空间:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="3.0" xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"> <persistence-unit name="default" transaction-type="RESOURCE_LOCAL"> <!-- 注意:JPA 3.0使用jakarta.persistence包路径,需同步修改实体类的import语句 --> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <class>com.example.demo.ActorEntity</class> <class>com.example.demo.AddressEntity</class> ... <properties> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/Sakila"/> <property name="hibernate.connection.driver_class" value="com.mysql.cj.jdbc.Driver"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="ß§%Y-Sn_ß-DF/n-/%D5-m274-§_9s%"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/> </properties> </persistence-unit> </persistence>
其他潜在问题修复
1. 消除SQL注入风险
你的查询方法直接拼接用户输入的ID,存在严重SQL注入漏洞,改为参数绑定方式:
public String getActorName(String id) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("default"); EntityManager em = emf.createEntityManager(); String query = "SELECT first_name, last_name from actor where actor_id = ?1"; Query actorQuery = em.createNativeQuery(query); actorQuery.setParameter(1, id); // 绑定参数,避免注入 List<String[]> actorName = actorQuery.getResultList(); String result = ""; if (!actorName.isEmpty()) { result = actorName.get(0)[0] + " " + actorName.get(0)[1]; } // 必须关闭资源,防止数据库连接泄漏 em.close(); emf.close(); return result; }
2. 移除冗余配置
你同时配置了persistence.xml和hibernate.cfg.xml,JPA模式下优先读取persistence.xml,hibernate.cfg.xml中的空配置可以直接删除,避免混淆。
内容的提问来源于stack exchange,提问作者Nils Burmester
相关产品推荐
相关产品推荐

