Hibernate 我们是否需要JPA关系和标准API

Hibernate 我们是否需要JPA关系和标准API,hibernate,jpa,jakarta-ee,criteria,jpql,Hibernate,Jpa,Jakarta Ee,Criteria,Jpql,背景: 我们使用的是一个传统的定制查询生成器,它基本上具有所有与查询相关的API。它在概念上或多或少等同于JPA标准API。自从我们从EJB2转移到EJB3之后,它对EJB2XML元数据的依赖性就一直困扰着我们。问题之一是,为了查询生成器,我们不得不维护/更新EJB2XML文件 作为EJB2到EJB3迁移的一部分,我们为所有表创建了实体类。但是,我们没有添加实体之间的关系 现在我们正在寻找摆脱它的方法,我们几乎决定使用JPA 两个想法: 考虑到API要求实体关系的标准,我有以下想法 实体关系伴随

背景:

我们使用的是一个传统的定制查询生成器,它基本上具有所有与查询相关的API。它在概念上或多或少等同于JPA标准API。自从我们从EJB2转移到EJB3之后,它对EJB2XML元数据的依赖性就一直困扰着我们。问题之一是,为了查询生成器,我们不得不维护/更新EJB2XML文件

作为EJB2到EJB3迁移的一部分,我们为所有表创建了实体类。但是,我们没有添加实体之间的关系

现在我们正在寻找摆脱它的方法,我们几乎决定使用JPA

两个想法:

考虑到API要求实体关系的标准,我有以下想法

  • 实体关系伴随着决定懒惰或渴望的包袱。在大多数情况下,急切地加载会导致性能问题,而延迟加载则要求在视图模式中打开会话,这也是问题所在
  • 尽管关系和标准API保护开发人员不受数据库sql的影响,但这在很大程度上被性能影响的风险所抵消,因为一个轻微的编程错误会导致大量的DB sql查询。为了避免这种情况,开发人员必须使用数据库,这使得数据库屏蔽成为一个问题
  • 到目前为止,业务逻辑负责在另一个实体之前保留哪个实体。使用CascadeType将其移动到实体层似乎没有任何好处
  • JPQL(NamedQueries和NamedNativeQueries)似乎和CriteriaAPI一样强大
  • 大多数Criteria API材料都声称Criteria API在过滤方面是最好的。然而,在参数和表联接的数量较多的情况下,这似乎很难成立 问题:

    也就是说,从广义上讲,实体关系似乎弊大于利

  • 使用实体关系的真实场景是什么
  • 哪些场景标准API超过了JPQL(命名和命名活动查询)
  • 任何想法都非常感谢

    提前感谢,


    Rakesh

    对于这个问题,什么场景标准API超过JPQL(命名和命名主动查询)-

    我们的项目中有RESTfulWeb服务,在我们的例子中,我们需要根据一些属性进行过滤。如果在过滤参数增加时使用查询方法,则查询也会增加。在这种情况下,标准api更好

    在下面的示例中,我们有2个查询参数,因此这两种方法都很好。但是如果您有4个或5个过滤查询参数,那么criteria api是最好的选择

     public List<AccountEntity> createCriteriaQuery(final List<String> accountIdList,
                    final MultiValueMap<String, String> allRequestParams) {
    
                final EntityManager entityManager = entityManagerFactory.createEntityManager();
                final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    
                final CriteriaQuery<AccountEntity> cq = cb.createQuery(AccountEntity.class);
                final Root<AccountEntity> accountEntity = cq.from(AccountEntity.class);
    
                final Join<AccountEntity, PlanEntity> account = accountEntity.join(AccountEntity_.planEntity);
    
                final List<Predicate> predicates = new ArrayList<Predicate>();
                    predicates.add(accountEntity.get(AccountEntity_.id).in(accountIdList));
    
                if (!allRequestParams.isEmpty()) {
                    if (allRequestParams.containsKey(ApplicationConstants.QUERYPARAM_ACCOUNTTYPE)) {
                        String accountType = allRequestParams.get(ApplicationConstants.QUERYPARAM_ACCOUNTTYPE).get(0);
                        if (accountType.equalsIgnoreCase(ApplicationConstants.ACCOUNTTYPE_POINT)) {
                            accountType = ApplicationConstants.ACCOUNTTYPE_PTS;
                        }
                        predicates.add(cb.equal(accountEntity.get(AccountEntity_.accounttype), accountType));
                    }
    
                    if (allRequestParams.containsKey(ApplicationConstants.QUERYPARAM_PLANNAME)) {
                        final String planName = allRequestParams.get(ApplicationConstants.QUERYPARAM_PLANNAME).get(0);
    
                        predicates.add(cb.like(account.get(PlanEntity_.name), "%" + planName + "%"));
                    }
                }
                cq.select(accountEntity).where(predicates.toArray(new Predicate[] {}));
                cq.orderBy(cb.asc(account.get(PlanEntity_.name)));
                final TypedQuery<AccountEntity> qry = entityManager.createQuery(cq);
    
                return qry.getResultList();
            }
    
    public List createCriteriaQuery(最终列表accountIdList,
    最终多值映射(所有请求参数){
    final EntityManager EntityManager=EntityManager工厂。createEntityManager();
    最终CriteriaBuilder cb=entityManager.getCriteriaBuilder();
    最终标准查询cq=cb.createQuery(AccountEntity.class);
    最终根accountEntity=cq.from(accountEntity.class);
    最终联接帐户=accountEntity.Join(accountEntity_u2;planEntity);
    最终列表谓词=new ArrayList();
    add(accountEntity.get(accountEntity.id).in(accountIdList));
    如果(!allRequestParams.isEmpty()){
    if(allRequestParams.containsKey(ApplicationConstants.QUERYPARAM\u ACCOUNTTYPE)){
    String accountType=allRequestParams.get(ApplicationConstants.QUERYPARAM\u accountType).get(0);
    if(accountType.equalsIgnoreCase(ApplicationConstants.accountType_点)){
    accountType=ApplicationConstants.accountType\u PTS;
    }
    add(cb.equal(accountEntity.get(accountEntity.accounttype),accounttype));
    }
    if(allRequestParams.containsKey(ApplicationConstants.QUERYPARAM_PLANNAME)){
    最终字符串planName=allRequestParams.get(ApplicationConstants.QUERYPARAM\u planName.get(0);
    add(cb.like(account.get(plantity_uu.name),“%”+planName+“%”);
    }
    }
    select(accountEntity).where(predicates.toArray(newpredicate[]{}));
    cq.orderBy(cb.asc(account.get(plantity_u41; name));
    最终类型dquery qry=entityManager.createQuery(cq);
    返回qry.getResultList();
    }
    
    对于这个问题,什么场景标准API超过JPQL(命名和命名主动查询)-

    我们的项目中有RESTfulWeb服务,在我们的例子中,我们需要根据一些属性进行过滤。如果在过滤参数增加时使用查询方法,则查询也会增加。在这种情况下,标准api更好

    在下面的示例中,我们有2个查询参数,因此这两种方法都很好。但是如果您有4个或5个过滤查询参数,那么criteria api是最好的选择

     public List<AccountEntity> createCriteriaQuery(final List<String> accountIdList,
                    final MultiValueMap<String, String> allRequestParams) {
    
                final EntityManager entityManager = entityManagerFactory.createEntityManager();
                final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    
                final CriteriaQuery<AccountEntity> cq = cb.createQuery(AccountEntity.class);
                final Root<AccountEntity> accountEntity = cq.from(AccountEntity.class);
    
                final Join<AccountEntity, PlanEntity> account = accountEntity.join(AccountEntity_.planEntity);
    
                final List<Predicate> predicates = new ArrayList<Predicate>();
                    predicates.add(accountEntity.get(AccountEntity_.id).in(accountIdList));
    
                if (!allRequestParams.isEmpty()) {
                    if (allRequestParams.containsKey(ApplicationConstants.QUERYPARAM_ACCOUNTTYPE)) {
                        String accountType = allRequestParams.get(ApplicationConstants.QUERYPARAM_ACCOUNTTYPE).get(0);
                        if (accountType.equalsIgnoreCase(ApplicationConstants.ACCOUNTTYPE_POINT)) {
                            accountType = ApplicationConstants.ACCOUNTTYPE_PTS;
                        }
                        predicates.add(cb.equal(accountEntity.get(AccountEntity_.accounttype), accountType));
                    }
    
                    if (allRequestParams.containsKey(ApplicationConstants.QUERYPARAM_PLANNAME)) {
                        final String planName = allRequestParams.get(ApplicationConstants.QUERYPARAM_PLANNAME).get(0);
    
                        predicates.add(cb.like(account.get(PlanEntity_.name), "%" + planName + "%"));
                    }
                }
                cq.select(accountEntity).where(predicates.toArray(new Predicate[] {}));
                cq.orderBy(cb.asc(account.get(PlanEntity_.name)));
                final TypedQuery<AccountEntity> qry = entityManager.createQuery(cq);
    
                return qry.getResultList();
            }
    
    public List createCriteriaQuery(最终列表accountIdList,
    最终多值映射(所有请求参数){
    final EntityManager EntityManager=EntityManager工厂。createEntityManager();
    最终CriteriaBuilder cb=entityManager.getCriteriaBuilder();
    最终标准查询cq=cb.createQuery(AccountEntity.class);
    最终根accountEntity=cq.from(accountEntity.class);
    最终联接帐户=accountEntity.Join(accountEntity_u2;planEntity);
    最终列表谓词=new ArrayList();
    add(accountEntity.get(accountEntity.id).in(accountIdList));
    如果(!allRequestParams.isEmpty()){
    if(allRequestParams.containsKey(ApplicationConstants.QUERYPARAM\u ACCOUNTTYPE)){
    String accountType=allRequestParams.get(ApplicationConstants.QUERYPARAM\u accountType).get(0);