ManyToMany关系更新?

时间:2014-07-29 14:33:37

标签: java hibernate jpa many-to-many persistence

我正在努力坚持@ManyToMany的关系。我创建了一个使用@IdClass进行关联的关联类,但是使用persist不起作用,只能使用merge。我需要添加其他寄存器,但使用merge不起作用,因为寄存器总是更新。

我希望数据库中的表格看起来像这样

id_aluno  | id_graduacao  |  grau   |  date    
  1              1           FIRST    2014-08-02
  1              1           SECOND   2014-08-02
  1              1           THIRD    2014-08-02

实体

@Entity
@Table(name="aluno")
public class Aluno implements Serializable{
    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue
    private Integer id;

    //informacoes gerais
    @NotNull
    private String nome;

    //historico de graduacao
    @OneToMany(mappedBy = "aluno")
    private List<HistoricoDeGraduacao> listaHistoricoGraduacao;

    public Aluno(){}

    /** adiciona lista de HistoricoDeGraduacao para aluno */
    public void addListaHistoricoGraduacao(HistoricoDeGraduacao hdg){
        if(listaHistoricoGraduacao == null){
            listaHistoricoGraduacao = new ArrayList<HistoricoDeGraduacao>();
        }
        listaHistoricoGraduacao.add(hdg);        
    }

    public List<HistoricoDeGraduacao> getListaHistoricoGraduacao() {
        return listaHistoricoGraduacao;
    }
    ///gets e sets


@Entity
@Table(name="graduacao")
public class Graduacao implements Serializable{
    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue
    private Integer id;

    @NotNull @Column(unique = true)
    private String graduacao;

    @ElementCollection
    @CollectionTable(name="graus_graduacao", joinColumns=@JoinColumn(name="id_graduacao"))
    @Column(name="graus")
    private List<String> graus;

    @OneToMany(mappedBy = "graduacao")
    private List<HistoricoDeGraduacao> listaHistoricoGraduacao;

    public Graduacao() {
    }

    /** adiciona historicodegraduacao a graduacao */
    public void addHistoricoDeGraduacao(HistoricoDeGraduacao hdg){
        if(listaHistoricoGraduacao == null){
            listaHistoricoGraduacao = new ArrayList<HistoricoDeGraduacao>();
        }
        listaHistoricoGraduacao.add(hdg);
    }

    public List<HistoricoDeGraduacao> getListaHistoricoGraduacao() {
        return listaHistoricoGraduacao;
    }
    //gets e sets



public class HistoricoDeGraduacaoId implements Serializable {
    private static final long serialVersionUID = 1L;

    private Aluno aluno;    
    private Graduacao graduacao;

    public Aluno getAluno() {
        return aluno;
    }

    public void setAluno(Aluno aluno) {
        this.aluno = aluno;
    }

    public Graduacao getGraduacao() {
        return graduacao;
    }

    public void setGraduacao(Graduacao graduacao) {
        this.graduacao = graduacao;
    }



@Entity
@IdClass(HistoricoDeGraduacaoId.class)
public class HistoricoDeGraduacao implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @ManyToOne 
    @JoinColumn(name = "id_aluno")
    private Aluno aluno;

    @Id
    @ManyToOne
    @JoinColumn(name="id_graduacao")
    private Graduacao graduacao;

    private String grau;

    @Temporal(TemporalType.DATE)
    private Date dataGraduou;

    public HistoricoDeGraduacao() {
    }
    //gets e sets


    //persisting
    public void insert(){ 
        //doesn't work using persist, works only with merge but record is always updated and not added
        em.getTransaction().begin();

        Aluno a = new Aluno(); 
        a.setId(1); //aluno have Id

        Graduacao g = new Graduacao();
        g.setId(1); //graduacao have Id

        HistoricoDeGraduacao hdg1 = new HistoricoDeGraduacao();
        hdg1.setAluno(a);
        hdg1.setGraduacao(g);
        hdg1.setDataGraduou(new Date());
        hdg1.setGrau("FIRST");
        a.addHistoricoDeGraduacao(hdg1);
        g.addHistoricoDeGraduacao(hdg1);
        em.persist(hdg1); 
        em.getTransaction().commit();

        HistoricoDeGraduacao hdg2 = new HistoricoDeGraduacao();
        hdg2.setAluno(a);
        hdg2.setGraduacao(g);
        hdg2.setDataGraduou(new Date());
        hdg2.setGrau("SECOND");
        a.addHistoricoDeGraduacao(hdg2);
        g.addHistoricoDeGraduacao(hdg2);
        em.persist(hdg2); 
        em.getTransaction().commit();

        HistoricoDeGraduacao hdg3 = new HistoricoDeGraduacao();
        hdg3.setAluno(a);
        hdg3.setGraduacao(g);
        hdg3.setDataGraduou(new Date());
        hdg3.setGrau("THIRD");
        a.addHistoricoDeGraduacao(hdg3);
        g.addHistoricoDeGraduacao(hdg3);
        em.persist(hdg3); 
        em.getTransaction().commit();

        em.close();
    }

使用persist不起作用,使用合并工作,但记录总是更新,而不是我需要添加新记录。

知道我该怎么办?

1 个答案:

答案 0 :(得分:1)

经过几天的搜索和尝试解决方案后,终于有效了!

这里我是怎么做的

@Entity
@Table(name="aluno")
public class Aluno implements Serializable{
    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue
    private Integer id;

    //informacoes gerais
    @NotNull
    private String nome;


    //historico de graduacao
    @OneToMany(mappedBy = "aluno", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<HistoricoDeGraduacao> listaHistoricoGraduacao;


    public Aluno() {
    }

    public void addListaHistoricoGraduacao(HistoricoDeGraduacao hdg){
        if(listaHistoricoGraduacao == null){
            listaHistoricoGraduacao = new ArrayList<HistoricoDeGraduacao>();
        }
        listaHistoricoGraduacao.add(hdg);        
    }


    public Integer getId() {
        return id;
    }

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

    public String getNome() {
        return nome;
    }

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

    public List<HistoricoDeGraduacao> getListaHistoricoGraduacao() {
        return listaHistoricoGraduacao;
    }

    public void setListaHistoricoGraduacao(List<HistoricoDeGraduacao> listaHistoricoGraduacao) {
        this.listaHistoricoGraduacao = listaHistoricoGraduacao;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Aluno other = (Aluno) obj;
        return true;
    }    
}


@Entity
@Table(name="graduacao")
public class Graduacao implements Serializable{
    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue
    private Integer id;

    @NotNull @Column(unique = true)
    private String graduacao;

    @ElementCollection
    @CollectionTable(name="graus_graduacao", joinColumns=@JoinColumn(name="id_graduacao"))
    @Column(name="graus")
    private List<String> graus;

    @OneToMany(mappedBy = "graduacao", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<HistoricoDeGraduacao> listaHistoricoGraduacao;

    public Graduacao() {
    }

    public Graduacao(Integer id, String graduacao, List<String> graus) {
        this.id = id;
        this.graduacao = graduacao;
        this.graus = graus;
    }   

    /** adiciona historicodegraduacao a graduacao */
    public void addHistoricoDeGraduacao(HistoricoDeGraduacao hdg){
        if(listaHistoricoGraduacao == null){
            listaHistoricoGraduacao = new ArrayList<HistoricoDeGraduacao>();
        }
        listaHistoricoGraduacao.add(hdg);
    }

    public Integer getId() {
        return id;
    }

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

    public String getGraduacao() {
        return graduacao;
    }

    public void setGraduacao(String graduacao) {
        this.graduacao = graduacao;
    }

    public List<String> getGraus() {
        return graus;
    }

    public void setGraus(List<String> graus) {
        this.graus = graus;
    }

    public List<HistoricoDeGraduacao> getListaHistoricoGraduacao() {
        return listaHistoricoGraduacao;
    }

    public void setListaHistoricoGraduacao(List<HistoricoDeGraduacao> listaHistoricoGraduacao) {
        this.listaHistoricoGraduacao = listaHistoricoGraduacao;
    }

    public String toString(){
        return graduacao;
    }
}


@Embeddable
public class HistoricoDeGraduacaoId implements Serializable {
    private static final long serialVersionUID = 1L;

    @JoinColumn(name="EMP_ID")
    private Integer id;

    public Integer getId() {
        return id;
    }

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


    @Override
    public boolean equals(Object obj) {
        return super.equals(obj); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public int hashCode() {
        return super.hashCode(); //To change body of generated methods, choose Tools | Templates.
    } 
}


@Entity
public class HistoricoDeGraduacao implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    HistoricoDeGraduacaoId pk;

    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "id_aluno")
    private Aluno aluno;    

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="id_graduacao")
    private Graduacao graduacao;

    private String grau;

    @Temporal(TemporalType.DATE)
    private Date dataGraduou;

    public HistoricoDeGraduacao() {
    }

    public void begin(){
        //instancia pk
        pk = new HistoricoDeGraduacaoId();
        //aqui insiro o id 
        pk.setId(new HistoricoDeGraduacaoDAO().getIndex());
    }


    public HistoricoDeGraduacaoId getPk() {
        return pk;
    }

    public void setPk(HistoricoDeGraduacaoId pk) {
        this.pk = pk;
    }

    public Aluno getAluno() {
        return aluno;
    }

    public void setAluno(Aluno aluno) {
        this.aluno = aluno;
    }

    public Graduacao getGraduacao() {
        return graduacao;
    }

    public void setGraduacao(Graduacao graduacao) {
        this.graduacao = graduacao;
    }

    public String getGrau() {
        return grau;
    }

    public void setGrau(String grau) {
        this.grau = grau;
    }

    public Date getDataGraduou() {
        return dataGraduou;
    }

    public void setDataGraduou(Date dataGraduou) {
        this.dataGraduou = dataGraduou;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 59 * hash + Objects.hashCode(this.aluno);
        hash = 59 * hash + Objects.hashCode(this.graduacao);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final HistoricoDeGraduacao other = (HistoricoDeGraduacao) obj;
        if (!Objects.equals(this.aluno, other.aluno)) {
            return false;
        }
        if (!Objects.equals(this.graduacao, other.graduacao)) {
            return false;
        }
        return true;
    }    
}


//aqui meu jframe com seus componentes, pegando valores montando tudo para ser salvo
     historico.setDataGraduou(jdp_dataGraduou.getDate());
     historico.setGrau(jl_graus.getSelectedValue().toString());
     //pega graduacao do jcombobox
     Graduacao g = (Graduacao)cbx_graduacao.getSelectedItem();                                
     historico.setGraduacao(g);
     //bean aluno
     historico.setAluno(bean);
     //add a listas
     bean.addListaHistoricoGraduacao(historico);
     g.addHistoricoDeGraduacao(historico);
     //inicia instancia de pk e insere o proximo id     
     historico.begin(); 
     //salva tudo
     new HistoricoDeGraduacaoDAO().update(historico);


//aqui meu DAO
public class HistoricoDeGraduacaoDAO {
    private EntityManager em;

    public HistoricoDeGraduacaoDAO(){
        em = Persistencia.getEntityManager();
    }

    /** pega o ultimo valor da tabela HistoricoDeGraduacao e adiciona + 1 para o proximo indice */
    public Integer getIndex(){
        int count = 0;
        Query query = em.createQuery("SELECT MAX(hdg.pk.id) FROM HistoricoDeGraduacao hdg");
        if(query.getSingleResult() == null){
            ++count;
        }else{
            count = (int)query.getSingleResult() + 1;            
        }
        return count;
    }

    /** executa update */
    public void update(HistoricoDeGraduacao historico){
        try{
            em.getTransaction().begin();        
            em.merge(historico);
            em.getTransaction().commit();
        }catch(PersistenceException e){
            JOptionPane.showMessageDialog(null, e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
        }finally{
            em.close();
        }
    }
}

结果是:enter image description here