【问题标题】:Hibernate CriteriaBuilder : Not an entity when it is an entityHibernate CriteriaBuilder:当它是实体时不是实体
【发布时间】:2021-08-28 10:25:46
【问题描述】:

我有一个包含 30 个左右实体的工作应用程序。主要使用自动生成查询的 CRUD 存储库。现在,有些查询没有优化,我想使用 Entity Graph 系统来连接其中的一些表。

到目前为止一切顺利,我遵循了几个教程并编写了代码。剩下的唯一问题是,当我运行它时,我收到了这个错误:

Not an entity: class com.stingray.syncmanager.models.StationRoleModel

这很奇怪,因为就像我之前所说的,我的应用程序已经使用了这个实体。在我看来,实体管理器或会话没有“意识到”这些实体的存在,就像它们在单独的“上下文”中一样,如果这有意义的话。

谁能指出我正确的方向?这是我的代码:

CustomSqlRepository.java

public CustomSqlRepository(HibernateConfig hibernateConfig, EntityManager entityManager) {
    Map<String, String> settings = new HashMap<>();
    settings.put("connection.driver_class", hibernateConfig.getDriverClassName());
    settings.put("hibernate.connection.url", hibernateConfig.getConnectionUrl());
    settings.put("hibernate.connection.username", hibernateConfig.getUsername());
    settings.put("hibernate.connection.password", hibernateConfig.getPassword());
    settings.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    settings.put("hibernate.current_session_context_class", "thread");

    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
            .applySettings(settings).build();

    MetadataSources metadataSources = new MetadataSources(serviceRegistry);
    Metadata metadata = metadataSources.buildMetadata();

    sessionFactory = metadata.getSessionFactoryBuilder().build();
    this.entityManager = entityManager;
}

public Session getCurrentSession() {
    return sessionFactory.getCurrentSession();
}

@Override
public List<StationRoleModel> findAllByRole(RoleModel role) {
    EntityGraph<?> graph = entityManager.getEntityGraph("stationrole-entity-graph-with-station");

    try (Session session = getCurrentSession()) {
        Transaction transaction = session.beginTransaction();

        CriteriaBuilder builder = session.getCriteriaBuilder();

        //===================================================================
        //This line crashes with "Not an entity" which doesn't make sense at all because it IS an entity...
        //===================================================================
        CriteriaQuery<StationRoleModel> criteria = builder.createQuery(StationRoleModel.class);
            Root<StationRoleModel> from = criteria.from(StationRoleModel.class);
        criteria.select(from);
        criteria.where(builder.equal(from.get("role"), role));
        TypedQuery<StationRoleModel> typed = entityManager
                    .createQuery(criteria)
                    .setHint("javax.persistence.fetchgraph", graph);

        try {
            return typed.getResultList();
        } catch (final NoResultException nre) {
            return new ArrayList<>();
        } finally {
            transaction.commit();
        }
    }
}

StationRoleModel.java

@Entity(name = "StationRoleModel")
@Table(name = "station_role")
@Getter
@Setter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@NamedEntityGraph(name = "stationrole-entity-graph-with-station",
        attributeNodes = @NamedAttributeNode("station"))
public class StationRoleModel extends BaseEntity {
    ...
}

【问题讨论】:

    标签: java spring-boot hibernate entity hibernate-criteria


    【解决方案1】:

    在我看来,实体管理器或会话没有“意识到”这些实体的存在,就像它们在单独的“上下文”中一样,如果这有意义的话。

    那是因为情况如此。您传入了一个EntityManager,它与现有的EntityManagerFactory 相关联,因此也与SessionFactory 相关联,但在存储库的构造函数中,您正在创建一个新的SessionFactorySessionFactory/SessionEntityManagerFactory/EntityManager 的管理应该由容器(在你的情况下是 Spring)来完成,所以你不应该乱构建任何一个。只需将EntityManager@Autowired 一起注入即可。

    【讨论】:

    • Ok 肯定会重新访问此代码并尝试此操作。届时将批准您的答案(可能需要几周时间!)。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 2023-01-07
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 2018-08-08
    相关资源
    最近更新 更多