父子之间的javax持久性关系。最后一个孩子又是另一个孩子的父母

时间:2019-03-05 09:58:00

标签: java jpa persistence

我的情况是:实体父MainSpeech与子Messages。邮件又是实体附件的父项。

我尝试通过添加具有两个新附件的新Massage来保留/合并现有MainSpeech。 持久/合并失败,因为ID_MESSAGE为空。 ID_MESSAGE是将“带有附件的邮件”连接起来的先行密钥。

//Entity MainSpeech
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="mainSpeech")
public List<Messages> getMessages() {
    return messages;
}
public void setMessages(List<Messages> messages) {
    this.messages = messages;
}

//Entity Messages
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ID_MAINSPEECH",nullable=false)
public MainSpeech getMainSpeech() {
    return mainSpeech;
}
public void setMainSpeech(MainSpeech mainSpeech) {
    this.mainSpeech = mainSpeech;
}

@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="messages")
public List<Attachments> getAttachments() {
    return attachments;
}
public void setAttachments(List<Attachments> attachments) {
    this.attachments = attachments;
}


//Entity Attachments    
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ID_MESSAGE",nullable=false)
public Messages getMessages() {
    return messages;
}
public void setMessages(Messages messages) {
    this.messages = messages;
}

我的代码:

public String inviaRisposta() {

    //conversazione is MainSpeech and it is an instance of MainSpeech
    Messaggi messaggio = new Messaggi(autore,
            EnumStatoMessaggio.INVIATO.getValue(),
            testoMsg,
            userWorkContext.getProfiloMessaggistica(),
            identity.getCredentials().getUsername(),
            conversazione);
    //aggiornamento conversazione e inserimento messaggio
    conversazione.getMessaggi().add(messaggio);

    List<Allegati> allegati = new ArrayList<Allegati>();
    try {
        if (StringUtils.isNotBlank(fileNameAllegatoUno)) {
            Allegati allegato = new Allegati();
            allegato.setFile(fileAllegatoUno);
            allegato.setDataUpload(new Date());
            allegato.setNomeFile(fileNameAllegatoUno);
            allegati.add(allegato);
        }
        if (StringUtils.isNotBlank(fileNameAllegatoDue)) {
            Allegati allegato = new Allegati();
            allegato.setFile(fileAllegatoDue);
            allegato.setDataUpload(new Date());
            allegato.setNomeFile(fileNameAllegatoDue);
            allegati.add(allegato);
        }
        if (StringUtils.isNotBlank(fileNameAllegatoTre)) {
            Allegati allegato = new Allegati();
            allegato.setFile(fileAllegatoTre);
            allegato.setDataUpload(new Date());
            allegato.setNomeFile(fileNameAllegatoTre);
            allegati.add(allegato);
        }
    } catch (NoSuchAlgorithmException e) {
        logger.error("Errore nella lettura dell'allegato", e);
    } catch (IOException ioe) {
        logger.error("Errore nella lettura dell'allegato", ioe);
    }

    if (allegati.size() > 0) {
        messaggio.setAllegati(allegati);
        entityManager.merge(conversazione);
        entityManager.persist(messaggio);
        /* ERROR DISPLAY IN CONSOLE
        10:33:30,942 INFO  [STDOUT] Hibernate: 
            insert 
            into
                gm_messaggi
                (autore, id_conversazione, ts_creazione, ts_invio, ts_ultimo_aggiornamento, destinatario, letto_da_destinatario, mittente, stato, testo, utente_mittente) 
            values
                (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        10:33:30,957 INFO  [STDOUT] Hibernate: 
            insert 
            into
                gm_allegati
                (ts_upload, file, id_messaggio, nome_file) 
            values
                (?, ?, ?, ?)
        10:33:30,965 INFO  [STDOUT] 2019-03-05 10:33:30 WARN  JDBCExceptionReporter:233 - SQL Error: 1048, SQLState: 23000
        10:33:30,966 INFO  [STDOUT] 2019-03-05 10:33:30 ERROR JDBCExceptionReporter:234 - Column 'ID_MESSAGGIO' cannot be null
        10:33:50,260 SEVERE [application] javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not insert: [it.racomputer.teso.poste.twsign.conversazioni.entity.Allegati]
        javax.faces.el.EvaluationException: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not insert: [it.racomputer.teso.poste.twsign.conversazioni.entity.Allegati]         
        */
    } else {
        entityManager.merge(conversazione);
    }

    return "ok";

}

消息(Messaggi)实体:

package it.entity;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Type;

import it.racomputer.seam4ra.auth.entity.AbstractSurrogateKeyEntity;
import it.racomputer.teso.poste.twsign.enums.EnumProfiloMessaggistica;

@Entity
@Table(name = "GM_MESSAGGI")
public class Messaggi extends AbstractSurrogateKeyEntity implements Comparable<Messaggi> {

private static final long serialVersionUID = 7749659591617999027L;

private String autore;
private Date dataCreazione;
private Date dataUltimoAggiornamento;
private Date dataInvio;
private String stato;
private String testo;
private char mittente;
private char destinatario;
private String utenteMittente;
private Conversazioni conversazioni;
private boolean lettoDaDestinatario;
private List<Allegati> allegati = new ArrayList<Allegati>();

public Messaggi() {
    super();
}

public Messaggi(String autore, String stato, String testo, char mittente, String utenteMittente, Conversazioni conversazioni) {
    super();
    this.autore = autore;
    this.dataCreazione = new Date();
    this.dataUltimoAggiornamento = new Date();
    this.dataInvio = new Date();
    this.stato = stato;
    this.testo = testo;
    this.mittente = mittente;
    this.destinatario = EnumProfiloMessaggistica.not(mittente).getValue();
    this.utenteMittente = utenteMittente;
    this.conversazioni = conversazioni;
    this.lettoDaDestinatario = false;
}

public Messaggi(Messaggi messaggio) {
    super();
    this.autore = messaggio.getAutore();
    this.dataCreazione = messaggio.getDataCreazione();
    this.dataUltimoAggiornamento = messaggio.getDataUltimoAggiornamento();
    this.dataInvio = messaggio.getDataInvio();
    this.stato = messaggio.getStato();
    this.testo = messaggio.getTesto();
    this.mittente = messaggio.getMittente();
    this.destinatario = messaggio.getDestinatario();
    this.utenteMittente = messaggio.getUtenteMittente();
    this.conversazioni = messaggio.getConversazioni();
    this.lettoDaDestinatario = messaggio.isLettoDaDestinatario();
}

@Column(name="AUTORE", nullable=false, length=45)
public String getAutore() {
    return autore;
}
public void setAutore(String autore) {
    this.autore = autore;
}

@Column(name="TS_CREAZIONE", nullable=false)
public Date getDataCreazione() {
    return dataCreazione;
}
public void setDataCreazione(Date dataCreazione) {
    this.dataCreazione = dataCreazione;
}

@Column(name="TS_ULTIMO_AGGIORNAMENTO", nullable=false)
public Date getDataUltimoAggiornamento() {
    return dataUltimoAggiornamento;
}
public void setDataUltimoAggiornamento(Date dataUltimoAggiornamento) {
    this.dataUltimoAggiornamento = dataUltimoAggiornamento;
}

@Column(name="TS_INVIO", nullable=false)
public Date getDataInvio() {
    return dataInvio;
}
public void setDataInvio(Date dataInvio) {
    this.dataInvio = dataInvio;
}
@Override
public int compareTo(Messaggi m) {
    if (getDataInvio() == null || m.getDataInvio() == null) {
        return 0;
    }
    return getDataInvio().compareTo(m.getDataInvio());
}

@Column(name="STATO", nullable=false, length=30)
public String getStato() {
    return stato;
}
public void setStato(String stato) {
    this.stato = stato;
}

@Column(name="TESTO", nullable=false, length=1000)
public String getTesto() {
    return testo;
}
public void setTesto(String testo) {
    this.testo = testo;
}

@Column(name="MITTENTE", nullable=false, length=1)
public char getMittente() {
    return mittente;
}
public void setMittente(char mittente) {
    this.mittente = mittente;
}

@Column(name="DESTINATARIO", nullable=false, length=1)
public char getDestinatario() {
    return destinatario;
}
public void setDestinatario(char destinatario) {
    this.destinatario = destinatario;
}

@Column(name="UTENTE_MITTENTE", nullable=false, length=40)
public String getUtenteMittente() {
    return utenteMittente;
}
public void setUtenteMittente(String utenteMittente) {
    this.utenteMittente = utenteMittente;
}

@ManyToOne(fetch=FetchType.LAZY,targetEntity=Conversazioni.class)
@JoinColumn(name="ID_CONVERSAZIONE",nullable=false)
public Conversazioni getConversazioni() {
    return conversazioni;
}
public void setConversazioni(Conversazioni conversazioni) {
    this.conversazioni = conversazioni;
}

@Type(type = "yes_no")
@Column(name="LETTO_DA_DESTINATARIO", nullable=false, length=1)
public boolean isLettoDaDestinatario() {
    return lettoDaDestinatario;
}
public void setLettoDaDestinatario(boolean lettoDaDestinatario) {
    this.lettoDaDestinatario = lettoDaDestinatario;
}   
public boolean letto(char profiloMessaggistica) {
    if (profiloMessaggistica == getDestinatario() && !isLettoDaDestinatario()) {
        return false;
    } else {
        return true;
    }

}

@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,targetEntity=Allegati.class,mappedBy="messaggi")
public List<Allegati> getAllegati() {
    return allegati;
}
public void setAllegati(List<Allegati> allegati) {
    this.allegati = allegati;
}

public boolean isMsgMine (char profiloMessaggistica) {
    if (profiloMessaggistica == this.mittente) {
        return true;
    } else {
        return false;
    }
}

}

SuperClass定义主键生成:

package it.entity;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
public abstract class AbstractSurrogateKeyEntity implements Serializable
{
    private Long id;

    @Id
    @GeneratedValue
    @Column(name="OBJ_ID")
    public Long getId()
    {
        return id;
    }

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

2 个答案:

答案 0 :(得分:1)

您不需要此行:

entityManager.persist(messaggio);

这是因为您已经在此处添加了关联:

conversazione.getMessaggi().add(messaggio);

,然后用entityManager.merge(conversazione);保存。同样,在每个一对多的关系中,您都有cascade=CascadeType.ALL,因此孩子会得到持久化。

您所做的是插入一个已经在db中的对象。

答案 1 :(得分:0)

出于对我的代码的一般兴趣,这里缺少。我忘记了巩固父母与孩子之间关系的代码行:

allegato.setMessaggi(messaggio);