Duvida com List JPA[RESOLVIDO]

Estou usando JSF2, JPA2 (Hibernate), e SQL Server 2008 e tenho com um problema para salvar uma entidade com uma lista de outras entidades no banco de dados após remover um item desta lista. Ao salvar a entidade com a lista, a entidade é atualizada e os novos itens da lista são incluídos ao banco de dados, mas os itens removidos desta lista não são excluídos do banco de dados.

As entidades:

[code]@Entity
@Table(name = “tbProposta”)
@NamedQueries({@NamedQuery(name = “proposta.getAll”, query = “select p from Proposta p”)})
public class Proposta implements PersistentEntity {
private static final long serialVersionUID = 1L;

@Id
@Column(name = "cdProposta")
private Long id;

// ...

@OneToMany(cascade = CascadeType.ALL, mappedBy = "proposta")
@LazyCollection(LazyCollectionOption.FALSE)
private List<Posicionamento> posicionamentos;

public List<Posicionamento> getPosicionamentos() {
    return posicionamentos;
}

public void setPosicionamentos(List<Posicionamento> posicionamentos) {
    this.posicionamentos = posicionamentos;
}

public boolean addPosicionamento(Posicionamento posicionamento) {
    if (posicionamentos == null) {
        posicionamentos = new ArrayList<Posicionamento>();
    }

    if (posicionamentos.add(posicionamento)) {
        if (posicionamento != null) {
            posicionamento.setProposta(this);
        }
        return true;
    }
    return false;
}

public boolean removePosicionamento(Posicionamento posicionamento) {
    if (posicionamentos != null) {
        if (posicionamentos.remove(posicionamento)) {
            if (posicionamento != null) {
                posicionamento.setProposta(null);
            }
            return true;
        }
    }
    return false;
}

[/code]

Posicionamento:

@Entity
@Table(name = "tbPosicionamento")
public class Posicionamento implements Comparable<Posicionamento>, Serializable {
    private static final long serialVersionUID = 1L;

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

    @Column(name = "dsObservacaoPMO")
    private String observacao;

    @Column(name = "dtPosicionamento")
    @Temporal(TemporalType.DATE)
    private Date data;

    @ManyToOne
    @JoinColumn(name = "cdAvaliacao")
    private Avaliacao avaliacao;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "cdProposta")
    private Proposta proposta;

    public Posicionamento() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getObservacao() {
        return observacao;
    }

    public void setObservacao(String observacao) {
        this.observacao = observacao;
    }

    public Date getData() {
        return data;
    }

    public void setData(Date data) {
       this.data = data;
    }

    public Avaliacao getAvaliacao() {
        return avaliacao;
    }

    public void setAvaliacao(Avaliacao avaliacao) {
        this.avaliacao = avaliacao;

        if (avaliacao != null && avaliacao.getPosicionamentos() != null && !avaliacao.getPosicionamentos().contains(this)) {
            avaliacao.addPosicionamento(this);
        }
    }

    public Proposta getProposta() {
        return proposta;
    }

    public void setProposta(Proposta proposta) {
        this.proposta = proposta;

        if (proposta != null && proposta.getPosicionamentos() != null && !proposta.getPosicionamentos().contains(this)) {
            proposta.addPosicionamento(this);
        }
    }

    @Override
    public int hashCode() {
        final int prime = 7;
        int result = 11;
        result = prime * result + ((data == null) ? 0 : data.hashCode());
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj == null) {
            return false;
        }

        if (getClass() != obj.getClass()) {
            return false;
        }
        Posicionamento other = (Posicionamento) obj;

        if (data == null) {
            if (other.data != null) {
                return false;
            }
        } else if (!data.equals(other.data)) {
            return false;
        }

        if (id == null) {
            if (other.id != null) {
                return false;
            }
        } else if (!id.equals(other.id)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Posicionamento [id=" + id + ", observacao=" + observacao + ", data=" + data + "]";
    }

    @Override
    public int compareTo(Posicionamento other) {
        return data != null ? data.compareTo(other.data) : -1;
    }

O managedbean:

public abstract class AbstractManager {
    public EntityManagerFactory emf;

    public AbstractManager() {
        emf = Persistence.createEntityManagerFactory("pmo");
    }

    protected final <T> T doInTransaction(PersistenceAction<T> action) throws ManagerException {
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            T result = action.execute(em);
            em.getTransaction().commit();
            return result;
        } catch (Exception e) {
            try {
                em.getTransaction().rollback();
            } catch (Exception ex) {
                Logger.getLogger(AbstractManager.class.getName()).log(Level.SEVERE, null, ex);
            }
            throw new ManagerException(e);
        } finally {
            em.close();
        }
    }

    protected final void doInTransaction(PersistenceActionWithoutResult action) throws ManagerException {
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            action.execute(em);
            em.getTransaction().commit();
        } catch (Exception e) {
            try {
                em.getTransaction().rollback();
            } catch (Exception ex) {
                Logger.getLogger(AbstractManager.class.getName()).log(Level.SEVERE, null, ex);
            }
            throw new ManagerException(e);
        } finally {
            em.close();
        }
    }

    protected static interface PersistenceAction<T> {
        T execute(EntityManager em);
    }

    protected static interface PersistenceActionWithoutResult {
        void execute(EntityManager em);
    }

    protected void addMessage(String message) {
        addMessage(null, message, FacesMessage.SEVERITY_INFO);
    }

    protected void addMessage(String componentId, String message) {
        addMessage(componentId, message, FacesMessage.SEVERITY_INFO);
    }

    protected void addMessage(String message, Severity severity) {
        addMessage(null, message, severity);
    }

    protected void addMessage(String componentId, String message, Severity severity) {
        FacesContext.getCurrentInstance().addMessage(componentId, new FacesMessage(severity, message, message));
    }

    protected String getMessageForKey(String key) {
        FacesContext fc = FacesContext.getCurrentInstance();
        ResourceBundle rb = fc.getApplication().getResourceBundle(fc, "i18n");
        return rb.getString(key);
    }

    protected FacesMessage getFacesMessageForKey(String key) {
        return new FacesMessage(getMessageForKey(key));
    }

    protected Logger getLogger(Class<?> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class for logger is required.");
        }
        return Logger.getLogger(clazz.getName());
    }

    protected void publishEvent(Class<? extends SystemEvent> eventClass, Object source) {
        if (source != null) {
            FacesContext fc = FacesContext.getCurrentInstance();
            fc.getApplication().publishEvent(fc, eventClass, source);
        }
    }

    protected void subscribeToEvent(Class<? extends SystemEvent> eventClass, SystemEventListener listener) {
        FacesContext.getCurrentInstance().getApplication().subscribeToEvent(eventClass, listener);
    }

    protected void unsubscribeFromEvent(Class<? extends SystemEvent> eventClass, SystemEventListener listener) {
        FacesContext.getCurrentInstance().getApplication().unsubscribeFromEvent(eventClass, listener);
    }


@ManagedBean
@SessionScoped
public class PropostaManager extends AbstractManager implements Serializable {
    private static final long serialVersionUID = 1L;

    private Posicionamento posicionamento;
    private DataModel<Posicionamento> posicionamentos;
    private List<Posicionamento> posicionamentosList;

    public Posicionamento getPosicionamento() {
        return posicionamento;
    }

    public void setPosicionamento(Posicionamento posicionamento) {
        this.posicionamento = posicionamento;
    }

    public DataModel<Posicionamento> getPosicionamentos() {
        return posicionamentos;
    }

    public void setPosicionamentos(DataModel<Posicionamento> posicionamentos) {
        this.posicionamentos = posicionamentos;
    }

    public List<Posicionamento> getPosicionamentosList() {
        return posicionamentosList;
    }

    public void addPosicionamento(ActionEvent e) {
        if (proposta != null) {
            if (proposta.addPosicionamento(posicionamento)) {
                posicionamentosList.add(posicionamento);
            }
        }
        posicionamento = proposta.getUltimoPosicionamento();
        novoPosicionamento = false;
    }

    public void removePosicionamento(ActionEvent e) {
        if (proposta != null) {
            posicionamento = posicionamentos.getRowData();

            if (proposta.removePosicionamento(posicionamento)) {
                posicionamentosList.remove(posicionamento);
            }
        }
        proposta.getUltimoPosicionamento();
        novoPosicionamento = false;
    }

Método save:

[code]public String save() {
if (proposta != null) {
try {
Proposta merged = doInTransaction(new PersistenceAction() {

                public Proposta execute(EntityManager em) {
                    Projeto projeto = proposta.getProjeto();

                    if (proposta.isNew()) {
                        Query q = em.createNamedQuery("projeto.getLast");
                        Long id = ((Projeto) q.getSingleResult()).getId() + 1;

                        projeto.setId(id);
                        em.persist(projeto);

// proposta.setPosicionamentos(posicionamentosList);
proposta.setId(id);
em.persist(proposta);
} else if (!em.contains(proposta)) {
em.merge(projeto);

                        return em.merge(proposta);
                    }

                    return proposta;
                }
            });

            if (!proposta.equals(merged)) {
                proposta = merged;
                int i = propostasList.indexOf(proposta);

                if (i != -1) {
                    propostasList.set(i, merged);
                }
            }

            if (!propostasList.contains(merged)) {
                propostasList.add(merged);
            }
            getLogger(getClass()).log(Level.INFO, proposta + " has been saved");
            addMessage("Proposta salva", FacesMessage.SEVERITY_INFO);
        } catch (Exception e) {
            getLogger(getClass()).log(Level.SEVERE, "Error on try to save Proposta: " + proposta, e);
            addMessage("Erro ao salvar a Proposta", FacesMessage.SEVERITY_ERROR);
            return null;
        }
    }
    initialize();
    return "list";
}

[/code]

E a página:

[code] <rich:tab header=“Posicionamento”>
<rich:panel rendered="#{not propostaManager.novoPosicionamento}">
<h:outputLabel for=“ultimoObservacao” value=“Observação” />

<h:inputText id=“ultimoObservacao” value="#{propostaManager.proposta.ultimoPosicionamento.observacao}" />

                    <h:outputLabel for="ultimoData" value="Data" /><br />
                    <rich:calendar datePattern="dd/MM/yyyy" id="ultimoData" value="#{propostaManager.proposta.ultimoPosicionamento.data}" /><br />
  
                    <h:outputLabel for="ultimoAvaliacao" value="Avaliação" /><br />
                    <h:selectOneMenu converter="avaliacaoConverter" id="ultimoAvaliacao" value="#{propostaManager.proposta.ultimoPosicionamento.avaliacao}">
                         <f:selectItem itemLabel="Selecione uma avaliação" />
                         <f:selectItems itemLabel="#{avaliacao.nome}" itemValue="#{avaliacao}" value="#{avaliacaoManager.avaliacoes}" var="avaliacao" />
                    </h:selectOneMenu><br />
                    <h:commandButton actionListener="#{propostaManager.novoPosicionamento}" value="Novo"/>
              </rich:panel>

              <rich:panel rendered="#{propostaManager.novoPosicionamento}">
                    <h:outputLabel for="observacao" value="Observação" /><br />
                    <h:inputText id="observacao" value="#{propostaManager.posicionamento.observacao}" /><br />
  
                    <h:outputLabel for="data" value="Data" /><br />
                    <rich:calendar datePattern="dd/MM/yyyy" id="data" value="#{propostaManager.posicionamento.data}" /><br />
  
                    <h:outputLabel for="avaliacao" value="Avaliação" /><br />
                    <h:selectOneMenu converter="avaliacaoConverter" id="avaliacao" value="#{propostaManager.posicionamento.avaliacao}">
                         <f:selectItem itemLabel="Selecione uma avaliação" />
                         <f:selectItems itemLabel="#{avaliacao.nome}" itemValue="#{avaliacao}" value="#{avaliacaoManager.avaliacoes}" var="avaliacao" />
                    </h:selectOneMenu><br />
                    <h:commandButton actionListener="#{propostaManager.addPosicionamento}" value="ADICIONAR"/>
              </rich:panel>

              <rich:dataTable value="#{propostaManager.posicionamentos}" var="posicionamento">
                    <rich:column>
                         <f:facet name="header">
                               <h:outputText value="Observação" />
                         </f:facet>
                         <h:outputText value="#{posicionamento.observacao}" />
                    </rich:column>

                    <rich:column>
                         <f:facet name="header">
                               <h:outputText value="Data" />
                         </f:facet>
                         <h:outputText value="#{posicionamento.data}">
                               <f:convertDateTime pattern="dd/MM/yyyy" />
                         </h:outputText>
                    </rich:column>

                    <rich:column>
                         <f:facet name="header">
                               <h:outputText value="Avaliação" />
                         </f:facet>
                         <h:outputText value="#{posicionamento.avaliacao.nome}" />
                    </rich:column>


              </rich:dataTable>
        </rich:tab>
  </rich:tabPanel>

[/code]

Alguém sabe o que posso fazer para solucionar o problema?

Obrigado.

Tente isso

@OneToMany(cascade = CascadeType.ALL, mappedBy = "proposta", orphanRemoval=true)  
    @LazyCollection(LazyCollectionOption.FALSE)  
     private List<Posicionamento> posicionamentos; 

Abraços

1 curtida

tenta utilizar esta propriedade na anotação

orphanRemoval = true
@OneToMany(cascade = CascadeType.ALL, mappedBy="proposta", fetch=FetchType.LAZY)  
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)  

Pessoal, testei as duas opções…deu esse erro

16/09/2011 14:17:31 br.com.foursys.pmo.manager.AbstractManager doInTransaction GRAVE: null java.lang.IllegalStateException: Transaction not active at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:104) at br.com.foursys.pmo.manager.AbstractManager.doInTransaction(AbstractManager.java:29) at br.com.foursys.pmo.proposta.PropostaManager.save(PropostaManager.java:528) at br.com.foursys.pmo.proposta.PropostaManager.removePosicionamento(PropostaManager.java:300) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.el.parser.AstValue.invoke(AstValue.java:262) at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) at org.apache.myfaces.view.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:83) at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:78) at javax.faces.event.ActionEvent.processListener(ActionEvent.java:51) at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:344) at javax.faces.component.UICommand.broadcast(UICommand.java:103) at org.richfaces.component.RowKeyContextEventWrapper.broadcast(RowKeyContextEventWrapper.java:109) at org.richfaces.component.UIDataAdaptor.broadcast(UIDataAdaptor.java:451) at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:978) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:275) at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1289) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:716) at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:34) at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171) at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at br.com.foursys.pmo.usuario.UsuarioFilter.doFilter(UsuarioFilter.java:21) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:244) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) 16/09/2011 14:17:31 br.com.foursys.pmo.proposta.PropostaManager save GRAVE: Error on try to save Proposta: br.com.foursys.pmo.proposta.Proposta@71a9b093 br.com.foursys.pmo.manager.ManagerException: javax.persistence.RollbackException: Error while committing the transaction at br.com.foursys.pmo.manager.AbstractManager.doInTransaction(AbstractManager.java:33) at br.com.foursys.pmo.proposta.PropostaManager.save(PropostaManager.java:528) at br.com.foursys.pmo.proposta.PropostaManager.removePosicionamento(PropostaManager.java:300) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.el.parser.AstValue.invoke(AstValue.java:262) at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) at org.apache.myfaces.view.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:83) at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:78) at javax.faces.event.ActionEvent.processListener(ActionEvent.java:51) at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:344) at javax.faces.component.UICommand.broadcast(UICommand.java:103) at org.richfaces.component.RowKeyContextEventWrapper.broadcast(RowKeyContextEventWrapper.java:109) at org.richfaces.component.UIDataAdaptor.broadcast(UIDataAdaptor.java:451) at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:978) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:275) at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1289) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:716) at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:34) at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171) at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at br.com.foursys.pmo.usuario.UsuarioFilter.doFilter(UsuarioFilter.java:21) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:244) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Caused by: javax.persistence.RollbackException: Error while committing the transaction at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:93) at br.com.foursys.pmo.manager.AbstractManager.doInTransaction(AbstractManager.java:25) ... 41 more Caused by: javax.persistence.EntityNotFoundException: deleted entity passed to persist: [br.com.foursys.pmo.proposta.posicionamento.Posicionamento#<null>] at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1196) at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147) at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:81) ... 42 more 16/09/2011 14:17:33 org.apache.myfaces.config.annotation.Tomcat7AnnotationLifecycleProvider newInstance INFO: Creating instance of

Boa tarde,

este problema é outro, você está tentando excluir e criar um Posicionamento na mesma transação.

Faz o teste de exclusão com o Posicionamento já criado, deve funcionar a exclusão da maneira que te explicaram.

Essa mensagem só ocorreu apos usar as anotações passadas

a mensagem é a mesma, tanto usando @OneToMany(cascade = CascadeType.ALL, mappedBy="proposta", fetch=FetchType.LAZY) @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) quanto@OneToMany(cascade = CascadeType.ALL, mappedBy = "proposta", orphanRemoval=true) @LazyCollection(LazyCollectionOption.FALSE) private List<Posicionamento> posicionamentos;

alguem?

?