2014-10-31 10 views
0

JBoss Seam 및 JPA를 사용하여 엔티티를 업데이트하려고하지만 분리 된 엔티티의 일반적인 문제에 직면하고 있습니다. 나는 더 잘 설명 할 것이다.JBoss Seam의 EntityHome을 사용하여 JPA Entity 병합

두 개의 간단한 엔티티가 관련되어 있습니다. 이 관계는 주석으로 매핑됩니다.

@Entity 
@Table(name = "RATEIO", uniqueConstraints = { @UniqueConstraint(columnNames = { "cd_projeto", "cd_tarefa", "cd_colaborador", "dt_rateio_inicial", 
     "dt_rateio_final" }) }) 
@Audited 
public class Rateio implements java.io.Serializable { 

    private static final long serialVersionUID = 1564844894403478898L; 

    private Long cdRateio; 
    private Colaborador colaborador; 
    private Tarefa tarefa; 
    private Projeto projeto; 
    private Date dtRateioInicial; 
    private Date dtRateioFinal; 

    private boolean flagAtividade; 
    private TipoRateio tipo; 
    private List<DetalheRateio> detalheRateios = new ArrayList<DetalheRateio>(0); 

    public Rateio() { 
    } 

    public Rateio(Long cdRateio, Colaborador colaborador, Projeto projeto, Date dtRateioInicial, Date dtRateioFinal) { 
     this.cdRateio = cdRateio; 
     this.colaborador = colaborador; 
     this.projeto = projeto; 
     this.dtRateioInicial = dtRateioInicial; 
     this.dtRateioFinal = dtRateioFinal; 
    } 

    public Rateio(Long cdRateio, Colaborador colaborador, Projeto projeto, Date dtRateioInicial, Date dtRateioFinal, List<DetalheRateio> detalheRateios) { 
     this.cdRateio = cdRateio; 
     this.colaborador = colaborador; 
     this.projeto = projeto; 
     this.dtRateioInicial = dtRateioInicial; 
     this.dtRateioFinal = dtRateioFinal; 
     this.detalheRateios = detalheRateios; 
    } 

    @Id 
    @SequenceGenerator(name = "sg_RATEIO_SEQ", sequenceName = "RATEIO_SEQ", allocationSize = 1) 
    @GeneratedValue(generator = "sg_RATEIO_SEQ") 
    @Column(name = "CD_RATEIO", nullable = false, scale = 0) 
    public Long getCdRateio() { 
     return this.cdRateio; 
    } 

    public void setCdRateio(Long cdRateio) { 
     this.cdRateio = cdRateio; 
    } 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "CD_COLABORADOR", nullable = true) 
    public Colaborador getColaborador() { 
     return this.colaborador; 
    } 

    public void setColaborador(Colaborador colaborador) { 
     this.colaborador = colaborador; 
    } 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "CD_PROJETO", nullable = true) 
    public Projeto getProjeto() { 
     return this.projeto; 
    } 

    public void setProjeto(Projeto projeto) { 
     this.projeto = projeto; 
    } 

    @Column(name = "DT_RATEIO_INICIAL", nullable = false) 
    public Date getDtRateioInicial() { 
     return this.dtRateioInicial; 
    } 

    public void setDtRateioInicial(Date dtRateioInicial) { 
     this.dtRateioInicial = dtRateioInicial; 
    } 

    @Column(name = "DT_RATEIO_FINAL", nullable = true) 
    public Date getDtRateioFinal() { 
     return this.dtRateioFinal; 
    } 

    public void setDtRateioFinal(Date dtRateioFinal) { 
     this.dtRateioFinal = dtRateioFinal; 
    } 

    @OneToMany(targetEntity=DetalheRateio.class, mappedBy = "rateio") 
    public List<DetalheRateio> getDetalheRateios() { 
     return this.detalheRateios; 
    } 

    public void setDetalheRateios(List<DetalheRateio> detalheRateios) { 
     this.detalheRateios = detalheRateios; 
    } 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "CD_TAREFA", nullable = true) 
    public Tarefa getTarefa() { 
     return tarefa; 
    } 

    public void setTarefa(Tarefa tarefa) { 
     this.tarefa = tarefa; 
    } 

    @Enumerated(EnumType.ORDINAL) 
    public TipoRateio getTipo() { 
     return tipo; 
    } 

    public void setTipo(TipoRateio tipo) { 
     this.tipo = tipo; 
    } 

    @Transient 
    public boolean isFlagAtividade() { 
     return flagAtividade; 
    } 

    public void setFlagAtividade(boolean flagAtividade) { 
     this.flagAtividade = flagAtividade; 
    } 
} 

을 그리고 내 두 번째 엔티티 : :보세요

@Entity 
@Table(name = "DETALHE_RATEIO") 
@Audited 
public class DetalheRateio implements Serializable { 

    private static final long serialVersionUID = 4109721744851677683L; 

    private Long cdDetalheRateio; 
    private Rateio rateio; 
    private AtividadeOs atividadeOs; 
    private float vlPorcentagem; 

    public DetalheRateio() { 
    } 

    public DetalheRateio(Long cdDetalheRateio, Rateio rateio, AtividadeOs atividadeOs, float vlPorcentagem) { 
     this.cdDetalheRateio = cdDetalheRateio; 
     this.rateio = rateio; 
     this.atividadeOs = atividadeOs; 
     this.vlPorcentagem = vlPorcentagem; 
    } 

    @Id 
    @SequenceGenerator(name = "sg_DET_RATEIO_SEQ", sequenceName = "DET_RATEIO_SEQ", allocationSize = 1) 
    @GeneratedValue(generator = "sg_DET_RATEIO_SEQ") 
    @Column(name = "CD_DETALHE_RATEIO", nullable = false, scale = 0) 
    public Long getCdDetalheRateio() { 
     return this.cdDetalheRateio; 
    } 

    public void setCdDetalheRateio(Long cdDetalheRateio) { 
     this.cdDetalheRateio = cdDetalheRateio; 
    } 

    @ManyToOne(targetEntity = Rateio.class, cascade=CascadeType.ALL) 
    @JoinColumn(name = "CD_RATEIO", nullable = false) 
    public Rateio getRateio() { 
     return this.rateio; 
    } 

    public void setRateio(Rateio rateio) { 
     this.rateio = rateio; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "CD_ATIVIDADE_OS", nullable = false) 
    public AtividadeOs getAtividadeOs() { 
     return this.atividadeOs; 
    } 

    public void setAtividadeOs(AtividadeOs atividadeOs) { 
     this.atividadeOs = atividadeOs; 
    } 

    @Column(name = "VL_PORCENTAGEM", nullable = false, precision = 19, scale = 2, columnDefinition = "NUMBER") 
    public float getVlPorcentagem() { 
     return this.vlPorcentagem; 
    } 

    public void setVlPorcentagem(float vlPorcentagem) { 
     this.vlPorcentagem = vlPorcentagem; 
    } 
} 

확인을, 지금까지 너무 좋아. 이제 JBoss Seam에서 EntityHome을 확장 한 클래스가 있으며이 클래스는 내 엔티티를 업데이트하려고합니다. 코드는 다음과 같습니다.

@Name("rateioHome") 
public class RateioHome extends EntityHome<Rateio> { 

    @SuppressWarnings("unchecked") 
    @Override 
    @Transactional 
    public String update() { 
     String result = null; 
     boolean valid = true; 
     if (getPercentualTotal().doubleValue() < 100 || instance.getDetalheRateios().size() < 2) { 
      facesMessages.addFromResourceBundle(Severity.ERROR, "rateio.erro.atividade"); 
      valid = false; 
     } 

     if (instance.getDtRateioFinal() != null && instance.getDtRateioFinal().before(instance.getDtRateioInicial())) { 
      facesMessages.addFromResourceBundle(Severity.ERROR, "rateio.erro.data"); 
      valid = false; 
     } 

     if (valid) { 
      Rateio rateio = super.find(); 
      List<DetalheRateio> detalheRateios = getInstance().getDetalheRateios(); 
      List<DetalheRateio> detalheRateiosBd = rateio.getDetalheRateios(); 
      Map<Long, DetalheRateio> mapDetalheRateio = new HashMap<Long, DetalheRateio>(); 

      if (detalheRateiosBd != null && detalheRateiosBd.size() > 0) { 

       Rateio _rateio = getInstance(); 

       for (DetalheRateio item : detalheRateiosBd) { 

        if (item.getCdDetalheRateio() != null) { 

         item.getRateio().setDtRateioInicial(_rateio.getDtRateioInicial()); 
         item.getRateio().setDtRateioFinal(_rateio.getDtRateioFinal()); 
         mapDetalheRateio.put(item.getCdDetalheRateio(), item); 
        } 
       } 
      } 

      List<DetalheRateio> novos = (List<DetalheRateio>) CollectionUtils.subtract(detalheRateios, detalheRateiosBd); 
      List<DetalheRateio> excluidos = (List<DetalheRateio>) CollectionUtils.subtract(detalheRateiosBd, detalheRateios); 

      detalheRateiosBd.removeAll(excluidos); 
      detalheRateiosBd.addAll(novos); 

      setInstance(rateio); 
      result = super.update(); 
      getEntityManager().flush(); 
     } 
     return result; 
    } 
} 

이제 문제가 있습니다. 내가 줄에 엔티티 업데이트 할 그럴 필요시 :

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: br.com.entity.DetalheRateio

내가 EntityHome에 방법 merge을 찾기 위해 노력했다,하지만 난 아무것도 발견하지 않았습니다 : result = super.update();를, 나는이 예외에 직면하고있다. 이것은 내가 지원해야하는 레거시 코드이며 JBoss Seam에 대해서는 전문가가 아닙니다. 더 많은 정보가 필요하시면 알려주세요.

+0

병합을()'수상 귀하의 Ratio 엔티티가 실제로 관리되는 것처럼 도움이됩니다. 오류가 DetalheRateio 아이 분리에 대한 불평입니다. 아마도 어딘가에 그것을 유지하지 않고 어딘가에 새 인스턴스를 추가하고 있습니까? – Gimby

+0

안녕하세요. 여기 자식 개체를 분리 오전 생각 : 이 객체는 업데이트되어 (값), 다시'Rateio' 객체로 설정됩니다. 이제 JPA에서 EntityHome 내의 자식 객체를 어떻게 업데이트합니까? –

답변

0

방금 ​​해결책을 찾았습니다. Rateio 개체를 업데이트하기 전에 개체 목록 DetalheRateio을 병합 (지속)해야합니다. . 내가 개체 DetalheRateio가 Rateio 자식으로 JPA에 의해 자동으로 '지속됩니다 문질러서 내 실수 그래서, 나는이 어떻게 사용 수동으로 각 DetalheRateio 오브젝트 snipet 합병 :..

List<DetalheRateio> novos = (List<DetalheRateio>) CollectionUtils.subtract(detalheRateios, detalheRateiosBd); 
List<DetalheRateio> excluidos = (List<DetalheRateio>) CollectionUtils.subtract(detalheRateiosBd, detalheRateios); 
List<DetalheRateio> detalhesAlterados = new ArrayList<DetalheRateio>(); 

detalheRateiosBd.removeAll(excluidos); 
detalheRateiosBd.addAll(novos); 

for (DetalheRateio detalheExcluido : excluidos) { 
    getEntityManager().remove(detalheExcluido); 
} 

for (DetalheRateio dRateio : detalheRateios) { 
    detalhesAlterados.add(getEntityManager().merge(dRateio)); 
} 

rateio.setDetalheRateios(detalhesAlterados); 
setInstance(rateio); 
result = super.update(); 
getEntityManager().flush();