0

好吧,在我的概念中(如果我错了,请纠正我)延迟加载应该像这样工作:

想象一下,我有一个对象“Sell”和另一个“Itens”,我可以在其中执行此操作:sell.getItens() 或 sell.setItens(),仅用于 ilustrate。所以,当我使用 SQL 语句时,我只加载没有 itens 的 SELL,如下所示:“SELECT * FROM SELL”。

但是在我的代码的某个地方,当我尝试执行“sell.getItens().get(0).getPrice()”时,JPA/Hibernate 必须立即从 Sell 加载所有项目,因为这是“按需加载” .

我对么 ?如果是,这对我不起作用。

编辑1:更具体地说,当我尝试在JSF的dataTable中使用我的“itens”时发生错误,请查看代码:

<p:dataTable rowKey="#{item.id}" var="item"
                            value="#{consultaMB.consulta.itens}"
                            emptyMessage="Não foi encontrado nenhum registro"
                            id="dataTableItensConsulta"
                            selection="#{consultaMB.itemConsulta}" selectionMode="single"
                            rowIndexVar="rowIndex"
                            rowStyleClass="#{(rowIndex mod 2) eq 0 ? 'first-row' : 'second-row'}">

错误是:rowKey="#{item.id}":在类型 org.hibernate.collection.PersistentSet 上找不到属性 'id'

编辑2:这是我完整的“Consulta”课程,带有itens。

@Entity
@NamedQueries(value = {
        @NamedQuery(name = "Consulta.findByOrcamento", query = "SELECT c FROM Consulta c "
                + "JOIN FETCH c.orcamento "
                + "JOIN FETCH c.situacao "
                + "WHERE c.orcamento.id = :idOrcamento "
                + "ORDER BY c.dataHoraAgendada desc"),
        @NamedQuery(name = "Consulta.findItensByConsulta", query = "SELECT c.itens FROM Consulta c "
                + "JOIN c.itens " + "WHERE c.id = :idConsulta"),
        @NamedQuery(name = "Consulta.findAllCompleto", query = "SELECT c FROM Consulta c "
                + "JOIN FETCH c.orcamento "
                + "JOIN FETCH c.situacao "
                + "ORDER BY c.dataHoraAgendada desc") })
@Table(name = "consulta")
public class Consulta extends AbstractBean {

    public Consulta() {
        this.itens = new HashSet<ItemOrcamento>();
        this.itensConcluidos = new HashSet<ItemOrcamento>();
        this.fotos = new ArrayList<FotoConsulta>();
    }

    @Transient
    public static final String FIND_BY_ORCAMENTO = "Consulta.findByOrcamento";
    @Transient
    public static final String FIND_ALL_COMPLETO = "Consulta.findAllCompleto";
    @Transient
    public static final String FIND_ITENS_BY_CONSULTA = "Consulta.findItensByConsulta";

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_orcamento")
    private Orcamento orcamento;

    @Column(name = "data_hora_agendada")
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date dataHoraAgendada;

    @ManyToMany(fetch = javax.persistence.FetchType.LAZY)
    @JoinTable(name = "item_consulta", joinColumns = { @JoinColumn(name = "id_consulta") }, inverseJoinColumns = { @JoinColumn(name = "id_item_orcamento") })
    private Set<ItemOrcamento> itens;

    @ManyToMany(fetch = javax.persistence.FetchType.LAZY)
    @JoinTable(name = "item_concluido_consulta", joinColumns = { @JoinColumn(name = "id_item_orcamento", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "id_consulta", nullable = false, updatable = false) })
    private Set<ItemOrcamento> itensConcluidos;

    @Column
    private String observacoes;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_situacao")
    private SituacaoConsulta situacao;

    @Column(name = "motivo_reagendamento")
    private String motivoReagendamento;

    @Column(name = "motivo_cancelamento")
    private String movitoCancelamento;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "consulta", targetEntity = FotoConsulta.class)
    @Cascade({ org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
    private List<FotoConsulta> fotos;

    public Orcamento getOrcamento() {
        return orcamento;
    }

    public void setOrcamento(Orcamento orcamento) {
        this.orcamento = orcamento;
    }

    public Date getDataHoraAgendada() {
        return dataHoraAgendada;
    }

    public void setDataHoraAgendada(Date dataHoraAgendada) {
        this.dataHoraAgendada = dataHoraAgendada;
    }

    public Set<ItemOrcamento> getItens() {
        return itens;
    }

    public void setItens(Set<ItemOrcamento> itens) {
        this.itens = itens;
    }

    public void addItem(ItemOrcamento item) {
        this.itens.add(item);
    }

    public void removeItem(ItemOrcamento item) {
        this.itens.remove(item);
    }

    public String getObservacoes() {
        return observacoes;
    }

    public void setObservacoes(String observacoes) {
        this.observacoes = observacoes;
    }

    public SituacaoConsulta getSituacao() {
        return situacao;
    }

    public void setSituacao(SituacaoConsulta situacao) {
        this.situacao = situacao;
    }

    public String getMotivoReagendamento() {
        return motivoReagendamento;
    }

    public void setMotivoReagendamento(String motivoReagendamento) {
        this.motivoReagendamento = motivoReagendamento;
    }

    public String getMovitoCancelamento() {
        return movitoCancelamento;
    }

    public void setMovitoCancelamento(String movitoCancelamento) {
        this.movitoCancelamento = movitoCancelamento;
    }

    public List<FotoConsulta> getFotos() {
        return fotos;
    }

    public void setFotos(List<FotoConsulta> fotos) {
        this.fotos = fotos;
    }

    public void addFoto(FotoConsulta foto) {
        this.fotos.add(foto);
    }

    public void removerFoto(FotoConsulta foto) {
        for (int i = 0; i < this.fotos.size(); i++) {
            if (this.fotos.get(i).getFoto().equals(foto.getFoto())) {
                this.fotos.remove(i);
                break;
            }
        }
    }

    public Set<ItemOrcamento> getItensConcluidos() {
        return itensConcluidos;
    }

    public void setItensConcluidos(Set<ItemOrcamento> itensConcluidos) {
        this.itensConcluidos = itensConcluidos;
    }

    public void addItemConcluido(ItemOrcamento item) {
        this.itensConcluidos.add(item);
    }

    public void removeItemConcluido(ItemOrcamento item) {
        this.itensConcluidos.remove(item);
    }

}

编辑 3:好吧,我将我的 dataTable 更改为:

<p:dataTable rowKey="#{item.id}" var="item"
                            value="#{consultaMB.consulta.itensAsList}"

我在 Consulta 类中创建了方法“getItensAsList()”,一切正常。看:

 public List<ItemOrcamento> getItensAsList(){
        List<ItemOrcamento> itensAsList = new ArrayList<ItemOrcamento>();
        Iterator<ItemOrcamento> it = itens.iterator();
        while (it.hasNext())
            itensAsList.add(it.next());

        return itensAsList;
    }

我真的不知道 dataTable 在你的 value 属性中只接受“List”类型。

4

2 回答 2

0

您提到的异常与延迟加载无关。您尚未使用必要的 getter 和 setter 方法在类 PersistentSet 中定义适当的字段 id。

于 2013-11-12T00:45:27.003 回答
0

仅当您的对象仍处于托管状态时,这才是正确的。

如果没有,您首先必须合并它以将其重新附加到持久性上下文,以便在使用 getter(s) 时加载所有惰性属性。否则,您将在运行时出现 NullPointerException。

基本上,只要您留在事务中,您的对象就应该受到管理。如果您离开它然后尝试在另一个事务中再次使用您的对象(或不),您必须合并它,以便在另一个进程将它更新到您的数据库中时它是最新的 - 或者如果您更新了该对象的属性。

请参考此答案中的架构以全面了解生命周期: How to know if a detached JPA entity has been persisted or not?

于 2013-11-12T00:36:02.433 回答