嗯,在我的概念中(如果我错了,请纠正我)延迟加载应该是这样的:
想象一下,我有一个对象“卖”和另一个“Itens”,我可以这样做:sell.getItens()或sell.setItens(),只是为了ilustrate。因此,当我使用SQL语句时,我只需加载SELL而不使用itens,如下所示:“SELECT * FROM SELL”。
但是在我尝试做的代码的某个地方:“sell.getItens()。get(0).getPrice()”,JPA / Hibernate必须立即加载来自Sell的所有itens,因为这是一个“需求加载“。
我是对的吗?如果是的话,这对我不起作用。
编辑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”类型。
答案 0 :(得分:0)
仅当您的对象仍处于托管状态时才会出现这种情况。
如果没有,首先必须将其合并以将其附加到持久化上下文,以便在使用getter时加载所有延迟属性。否则,您将在运行时遇到NullPointerException。
基本上只要您保留在交易中,您的对象就应该保持管理状态。如果你离开它然后尝试再次使用你的对象在另一个事务中(或不是),你必须合并它,以便它是最新的,如果另一个进程将它更新到你的数据库 - 或者你更新了这个对象的属性。 / p>
请参阅此答案中的架构,以获得生命周期的全局概述: How to know if a detached JPA entity has already been persisted or not?
答案 1 :(得分:0)
您引用的异常与延迟加载无关。您尚未使用必要的getter和setter方法在PersistentSet类中定义适当的字段ID。