【问题标题】:Criteria API combine 2 enttiesCriteria API 结合了 2 个实体
【发布时间】:2016-12-06 21:04:45
【问题描述】:

我正在尝试使用帐户和条目实体之间的@OneToOne 关系过滤数据。 我需要做的是搜索具有 Account.glcode = "15"

的 Entry-s

这是我所做的,但它不起作用。

Root<?> root = mainQuery.from(Entry.class);
Predicate predicate = builder.conjunction();
Join<Entry,Account> entries = root.join("account");
predicate = builder.and((builder.equal(entries.get("glCode"),"15" )));

我的条目类

@Entity
public class Entry {

@Id
private Long id;
.........

@OneToOne
@JoinColumn(name = "account_id", nullable = false)
private Account account;

这是帐户类

@Entity
public class Account {

@Id @GeneratedValue
private Long id;
private Long glCode;

谁能告诉我我做错了什么?

谢谢

更新

  public PaginationResult getFilteredData(List<FilterConstraint> filters, Object classname) {
    try {
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<?> mainQuery = builder.createQuery(classname.getClass());
        Root<?> root = mainQuery.from(GLJournalEntry.class);
        Predicate predicate = builder.conjunction();

        Predicate enumPredicate = builder.conjunction();
        Predicate today = builder.conjunction();
        Predicate on = builder.conjunction();

        for (FilterConstraint constraint : filters) {

            //IT is hard coded right now for testing purpose but should be customized for the future 
            if(constraint.getField().getValue().contains("-")){
                String[] items = constraint.getField().getValue().split("-");
                Join<GLJournalEntry,GLAccount> entries = root.join("glAccount");
                predicate = builder.and((builder.equal(entries.get("glCode"), constraint.getValues().getValue())));
                entries.getAttribute().toString();
                break;
            }

            switch (constraint.getOperator()) {
                case AFTER:
                    predicate = builder.and(builder.greaterThan(root.get(constraint.getField().getValue()), constraint.getValues().getStartDate()));
                    break;
                case BEFORE:
                    predicate = builder.and(builder.greaterThan(root.get(constraint.getField().getValue()), constraint.getValues().getStartDate()));
                    break;
                case BETWEEN:
                    if (constraint.getField().getType() == FieldDataType.DATE) {
                        predicate = builder.and(builder.between(root.get(constraint.getField().getValue()), constraint.getValues().getStartDate(), constraint.getValues().getEndDate()));
                    } else if (constraint.getField().getType() == FieldDataType.INTEGER) {
                        predicate = builder.and(builder.between(root.get(constraint.getField().getValue()), Integer.valueOf(constraint.getValues().getMinValue()), Integer.valueOf(constraint.getValues().getMaxValue())));
                    } else {
                        predicate = builder.and(builder.between(root.get(constraint.getField().getValue()), constraint.getValues().getMinValue(), constraint.getValues().getMaxValue()));
                    }
                    break;
                case EMPTY:
                    predicate = builder.and(builder.isEmpty(root.get(constraint.getField().getValue())));
                    break;
                case EQUALS:
                    if (constraint.getField().getType() == FieldDataType.ENUM) {

                        Object enumV = null;

                        if (constraint.getValues().getEnumValue().size() > 1) {

                            List<Predicate> predicates = new ArrayList<>();
                            for (EnumValue enumValue : constraint.getValues().getEnumValue()) {


                                for (Field f : classname.getClass().getDeclaredFields()) {
                                    if (f.getName().equals(constraint.getField().getValue())) {
                                        System.out.println("T");
                                        Class<?> clz = f.getType();
                                        Object[] consts = clz.getEnumConstants();
                                        for (int i = 0; i < consts.length - 1; i++) {
                                            if (consts[i].toString().equals(enumValue.getValue())) {
                                                enumV = consts[i];
                                                break;
                                            }
                                        }
                                    }
                                }
                                predicates.add(builder.equal(root.get(constraint.getField().getValue()), enumV));
                            }

                            enumPredicate = builder.and(builder.or(predicates.toArray(new Predicate[]{})));
                            break;
                        }

                        for (Field f : classname.getClass().getDeclaredFields()) {
                            if (f.getName().equals(constraint.getField().getValue())) {
                                System.out.println("T");
                                Class<?> clz = f.getType();
                                Object[] consts = clz.getEnumConstants();
                                for (int i = 0; i < consts.length - 1; i++) {
                                    if (consts[i].toString().equals(constraint.getValues().getEnumValue().get(0).getValue())) {
                                        enumV = consts[i];
                                        break;
                                    }
                                }
                            }
                        }


                        enumPredicate = builder.equal(root.get(constraint.getField().getValue()), enumV);
                        break;
                    }
                    predicate = builder.and(builder.equal(root.get(constraint.getField().getValue()), constraint.getValues().getValue()));
                    break;
                case LESS_THAN:
                    predicate = builder.and(builder.lessThan(root.get(constraint.getField().getValue()), constraint.getValues().getValue()));
                    break;

                case MORE_THAN:
                    predicate = builder.and(builder.greaterThan(root.get(constraint.getField().getValue()), constraint.getValues().getValue()));
                    break;
                case NOT_EMPTY:
                    predicate = builder.and(builder.isNotEmpty(root.get(constraint.getField().getValue())));
                    break;
                case ON:
                    on = builder.between(root.get(constraint.getField().getValue()), DateUtils.getFirstSecondOfDate(constraint.getValues().getStartDate()), DateUtils.getLastSecondOfDate(constraint.getValues().getStartDate()));
                    break;
                case STARTS_WITH:

                case TODAY:
                    today = builder.and(builder.between(root.get(constraint.getField().getValue()), DateUtils.getFirstSecondOfDate(new Date()), DateUtils.getLastSecondOfDate(new Date())));
                    break;
            }


        }


        CriteriaQuery<Long> cq = builder.createQuery(Long.class);
        cq.select(builder.count(cq.from(classname.getClass())));
        em.createQuery(cq);
        cq.where(predicate, enumPredicate, today, on);
        Long count = em.createQuery(cq).getSingleResult();

        mainQuery.where(predicate, enumPredicate, today, on);


        //Count for pagination
        TypedQuery<?> q = em.createQuery(mainQuery);
        q.setMaxResults(filters.get(0).getCount());
        int firstResult = filters.get(0).getPage() * filters.get(0).getCount() - filters.get(0).getCount();
        q.setFirstResult(firstResult);


        PaginationResult result = new PaginationResult();
        result.setData((List<Client>) q.getResultList());
        result.setMaxResults(count);

        System.out.println(result.getData().size());

        return result;
    } catch (Exception e) {
        System.out.println(e.getMessage());
        return null;
    }

}

【问题讨论】:

    标签: java hibernate jpa criteria criteria-api


    【解决方案1】:

    glCode 的参数是一个字符串,但必须是长的。并使用更好的ParameterExpression,

    例子:

    public List<Entry> findEntryByGlCode(Long glCode) {
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    
        final CriteriaQuery<Entry> query = criteriaBuilder.createQuery(Entry.class);
        final Root<Entry> root = query.from(Entry.class);
    
        Join<Entry, Account> join = root.join("account");
        ParameterExpression<Long> glcodeParameter = criteriaBuilder.parameter(Long.class, "glCode");
        Predicate equal = criteriaBuilder.equal(join.get("glCode"), glcodeParameter);
    
        query.where(equal);
        query.select(root);
    
        return entityManager.createQuery(query).setParameter("glCode", glCode).getResultList();
    }
    

    【讨论】:

    • 它抛出一个错误:无法解析属性:glCode of: ge.shemo.model.accounting.glAccount.Entry
    • 你的类有getter/setter?
    • 请发表您的完整方法。
    • 我已经添加了完整的方法。我在开头粘贴了您的代码并带有注释 - 'IT 现在是硬编码的'
    • 你的方法很大。您的最后一个错误是找不到 ge.shemo.model.accounting.glAccount.Entry.getGlCode(),但是您发布了 Entry -> Account -> glCode。你的错不在于查询。
    猜你喜欢
    • 2018-07-04
    • 2016-11-28
    • 2018-10-16
    • 2012-03-15
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 2011-03-02
    • 2011-07-17
    相关资源
    最近更新 更多