【问题标题】:IllegalStateException using CriteriaBuilder for getting a List in JavaIllegalStateException 使用 CriteriaBuilder 在 Java 中获取列表
【发布时间】:2018-12-17 17:25:34
【问题描述】:

总结一下,我有 3 个实体,主要的一个是名为“Rac”的实体。它包含一个“RacNatureza”列表,其中包含一个属性“Natureza”。

拉克

    @Entity
    @Table(name = "rac")
    public class Rac {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idRac;    

    @OneToMany(mappedBy = "rac", cascade = {CascadeType.ALL}, orphanRemoval = true)
    @JsonManagedReference //para evitar recursão infinita do JSON
    private List<RacNatureza> racNaturezas;

    //...getters and setters ok
}

RacNatureza

@Entity
@Table(name = "rac_natureza")
public class RacNatureza implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_rac_natureza")
    private Long idRacNatureza;

    @ManyToOne
    @JsonBackReference //coloquei para evitar a recursao infinita de JSON
    @JoinColumn(name="id_rac")
    private Rac rac;

    @ManyToOne
    @JoinColumn(name="id_natureza")
    private Natureza natureza;

    @Column(name = "principal")
    private Boolean principal;
}

大自然

@Entity
@Table(name = "natureza")
public class Natureza {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_natureza")
    private Integer idNatureza;
    private String descricao;

    @OneToMany(mappedBy = "natureza", fetch = FetchType.EAGER, orphanRemoval = true)
    @JsonIgnore
    private List<RacNatureza> racNatureza;
}

我正在尝试使用过滤器开发搜索,在这种情况下,用户选择“Natureza”列表,然后系统必须显示“Rac”包含用户选择的 Natureza。为此,我尝试使用 Entitymanager 和 Criteriabuilder 来实现。

我试过这样写表达式,但没有用(我没有使用元模型):

@PersistenceContext
private EntityManager entityManager;

@Override
public List<Rac> filtrar(RacFilter racFilter) {
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Rac> criteria = builder.createQuery(Rac.class);
    Root<Rac> root = criteria.from(Rac.class);

    Predicate[] predicates = criarRestricoes(racFilter, builder, root);
    criteria.where(predicates);

    TypedQuery<Rac> query = entityManager.createQuery(criteria);
    return query.getResultList();

}

@Override
public Predicate[] criarRestricoes(RacFilter racFilter, CriteriaBuilder builder, Root<Rac> root) {
    List<Predicate> predicates = new ArrayList<>();
    if (racFilter.getNaturezas() != null) {
        predicates.add(
                builder.equal(root.<List<RacNatureza>>get("racNaturezas").<Natureza>get("natureza"), racFilter.getNaturezas()) );
    }   
    return predicates.toArray(new Predicate[predicates.size()]);
}

所以,使用上面的这段代码,我收到了以下错误: 原因:java.lang.IllegalStateException:非法尝试取消引用基本类型的路径源 [null.racNaturezas]

我相信错误在这一行,但我真的不知道如何解决它:

    predicates.add(
            builder.equal(root.<List<RacNatureza>>get("racNaturezas").<Natureza>get("natureza"), racFilter.getNaturezas()) );
}   

【问题讨论】:

    标签: java jpa criteria hibernate-criteria predicate


    【解决方案1】:

    替换root.get("racNaturezas") root.join("racNaturezas")

    请不要问我为什么我们不能使用get

    【讨论】:

      【解决方案2】:

      FWIW 您不能使用get,因为隐式连接仅针对多对一和一对一关联。它们不能用于多对多或一对多关联。在后一种情况下,需要显式连接,即root.join("racNaturezas")

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        • 2014-10-11
        相关资源
        最近更新 更多