Keycloak14使用EntityManager查询自定义表报实体未映射问题如何解决
报错根因
报错信息中的store_test_model is not mapped是Hibernate的JPQL查询语法错误,核心原因是JPQL语句要求使用Java实体类名作为查询对象,而非数据库表名,你代码中填写的store_test_model是数据库侧的表名,不在Hibernate的实体映射名单中,因此抛出异常。
此外你还存在两处配置疏漏:实体类未添加JPA必备的@Entity注解、获取的EntityManager默认关联Keycloak自身的持久化单元,未关联你自定义的api-extensions持久化单元,也会导致映射失败。
解决方案
按以下步骤依次修正即可:
- 修正JPQL查询语句,将表名替换为实体类名
StoreTestModel,修改后的代码如下:
StoreTestModel storeTestModel = em.createQuery("SELECT u FROM StoreTestModel u WHERE u.fieldOne = :fieldOne", StoreTestModel.class) .setParameter("fieldOne", "test one") .getSingleResult();
如果你确实需要直接写原生SQL操作数据库表,也可以使用原生查询方式:
StoreTestModel storeTestModel = (StoreTestModel) em.createNativeQuery("SELECT * FROM store_test_model WHERE field_one = :fieldOne", StoreTestModel.class) .setParameter("fieldOne", "test one") .getSingleResult();
- 给实体类补充JPA必备注解,明确实体和表的映射关系:
@Entity // 必须添加,标注该类为JPA实体类 @Table(name = "store_test_model") // 显式指定对应的数据库表名,避免默认映射规则出错 public class StoreTestModel { // 原有类内部代码无需改动 }
- 修正EntityManager获取方式,确保关联你自定义的
api-extensions持久化单元:
你当前从jpaConnectionProvider获取的EntityManager默认关联Keycloak自身的持久化单元,不会加载你自定义的实体类,改为以下方式获取:
// 按自定义持久化单元名称初始化EntityManager EntityManagerFactory emf = Persistence.createEntityManagerFactory("api-extensions"); EntityManager em = emf.createEntityManager();
如果需要和Keycloak共用事务,可以直接通过注解注入对应持久化单元的EntityManager:
@PersistenceContext(unitName = "api-extensions") private EntityManager em;
- 可选验证项:检查
persistence.xml中配置的实体类全限定名keycloak.apiextension.entity.StoreTestModel,要和你实际实体类的包路径、类名完全一致,不可出现拼写错误。
内容的提问来源于stack exchange,提问作者proton
相关产品推荐
相关产品推荐

