Problema/Dúvida em insert com ManyToMany - Hibernate

4 respostas
painkiller

Salve Galera!! Pessoal estou com um problema aqui que está me deixando preso…

seguinte…

Tenho duas tabelas: Equipamentos e Funções…

Cada uma delas é representada por um Bean mapeado por annotations… beleza…

Fiz o mapeamento e tal, tudo certo… e até consegui fazer a inserção em um main que criei pra teste. Contudo, quando eu vou inserir novamente não consigo, ele gera um erro assim:

GRAVE: Could not synchronize database state with session

org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)

at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)

at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)

at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)

at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:145)

at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)

at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)

at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)

at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)

at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)

at com.sisgae.dao.EquipamentoDAO.insert(EquipamentoDAO.java:52)

at com.sisgae.actions.EquipamentoActions.salvar(EquipamentoActions.java:68)

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:191)

at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)

at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:68)

at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:77)

at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:91)

at javax.faces.component.UICommand.broadcast(UICommand.java:383)

at org.ajax4jsf.component.AjaxActionComponent.broadcast(AjaxActionComponent.java:55)

at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:329)

at org.ajax4jsf.component.AjaxViewRoot.broadcastEventsForPhase(AjaxViewRoot.java:304)

at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:261)

at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:474)

at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:97)

at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)

at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)

at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)

at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)

at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)

at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)

at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)

at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)

at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)

at java.lang.Thread.run(Thread.java:619)

Caused by: java.sql.BatchUpdateException: Entrada em lote 1 insert into funcao_has_equipamento (equipamento_idequipamento, funcao_idfuncao) values (5555, 2) foi abortada. Chame getNextException para ver a causa.

at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2569)

at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1796)

at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:407)

at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2708)

at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)

at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)

 49 more

Eu acho que entendi o porquê desse erro, acho que é porque ta repetindo a PK da tabela relacional funcao_has_equipamento. Mas a minha dúvida é: Como eu vou criar uma sequence ou como vou resolver isso sendo que a classe que representa essa tabela relacional não existe, é criada automaticamente pelo hibernate!!??? =/

Pô galera, quem puder me ajudar… da uma forcinha aê!! Obrigado!!

4 Respostas

DeGuedes

Cara, isso aconteceu muito comigo… sofri pra descobrir o que era… :smiley:
O que esta acontecendo é o sguinte ele esta tentando inserir os registros com a msm chave (ID), por isso o primeiro da certo e o segundo não…

faça o seguinte, quando vc for setar os campos, sete o campo CHAVE como null, assim o banco de dados se obriga a criar uma nova chave para esse registro…

tente fazer isso se nao der acerto me avise, que te passo a classe q no qual faço essa inserção!

vlw

painkiller

Opaaa, valeu amigo!! entendi o que quis dizer, mas tipo… como eu vou setar null se na verdade a classe que representa a tabela relacional não existe? é o hibernate que cria ela! como eu faço?? Valeu a força, velho!!!

DeGuedes

se vc criou uma classe de entidade, o hibernate se encarrega de criar a tabela no banco de dados… vc nao precisa fazer nada!!!

:wink:

vc soh precisa setar o objeto, setando tambem a chave dele como null…

se tiver duvidas, posta a classe ai q eu te ajudo!! ;D

painkiller

Classe Equipamento

@Entity
@Table(name = "equipamento")
@SuppressWarnings("serial")
public class Equipamento implements Serializable {

    private Integer id;
    private String nome;
    private String marca;

    
    private List<EquipamentoFuncao> funcoes = new ArrayList<EquipamentoFuncao>();

    @Id
    @Column(name = "idequipamento")
    public Integer getId() {
        return id;
    }

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

    @Column(name = "nome")
    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    @Column(name = "marca")
    public String getMarca() {
        return marca;
    }

    public void setMarca(String marca) {
        this.marca = marca;
    }

    @ManyToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinTable(name="funcao_has_equipamento",joinColumns=@JoinColumn(name="equipamento_idequipamento"),
    inverseJoinColumns=@JoinColumn(name="funcao_idfuncao"))
    public List<EquipamentoFuncao> getFuncoes() {
        return funcoes;
    }

    public void setFuncoes(List<EquipamentoFuncao> funcoes) {
        this.funcoes = funcoes;
    }

}

Classe EquipamentoFuncao

@Entity
@Table(name = "funcao")
@SuppressWarnings("serial")
public class EquipamentoFuncao implements Serializable {

    public EquipamentoFuncao() {
    }
    private String especificacao;
    private Integer id;
    private List<Equipamento> equipamento;

    public EquipamentoFuncao(String especificacao) {
        this.especificacao = especificacao;
    }

    @Override
    public String toString() {
        return this.getEspecificacao();

    }

    @Column(name = "especificacao")
    public String getEspecificacao() {
        return especificacao;
    }

    public void setEspecificacao(String especificacao) {
        this.especificacao = especificacao;
    }

    @Id
    @Column(name = "idfuncao")
    public Integer getId() {
        return id;
    }

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


    @ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="funcao_has_equipamento",joinColumns=@JoinColumn(name="funcao_idfuncao"),
    inverseJoinColumns=@JoinColumn(name="equipamento_idequipamento"))
    public List<Equipamento> getEquipamento() {
        return equipamento;
    }

    public void setEquipamento(List<Equipamento> equipamento) {
        this.equipamento = equipamento;
    }
}

para inserir eu uso session.save, passando o obj por param...

aí como eu te disse, salva direitinho... mas aí não rola por causa da chave né... mas aí que é minha dúvida, como eu vou setar null pra PK da tabela relacional (funcao_has_equipamento) sendo que a classe entidade que representa ela não existe?? :( :( :( :(

Criado 14 de outubro de 2010
Ultima resposta 14 de out. de 2010
Respostas 4
Participantes 2