постоянные отношения между родителем и ребенком. Этот последний ребенок в свою очередь является родителем другого ребенка - PullRequest
0 голосов
/ 05 марта 2019

Моя ситуация такова: сущность родителя MainSpeech с дочерними сообщениями. Сообщения, в свою очередь, являются родителями объекта Attachment.

Я пытаюсь сохранить / объединить существующую MainSpeech, добавив новый массаж, в котором есть два новых приложения. Не удается сохранить / объединить, поскольку ID_MESSAGE имеет значение null. 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;
    }
}

}

Суперкласс для определения генерации первичного ключа:

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 ]

1 голос
/ 05 марта 2019

Вам не нужна эта строка:

entityManager.persist(messaggio);

Это потому, что вы уже добавляете здесь ассоциацию:

conversazione.getMessaggi().add(messaggio);

, а затем сохраните его с помощью entityManager.merge(conversazione);. Кроме того, во всех отношениях один-ко-многим у вас есть cascade=CascadeType.ALL, поэтому ребенок сохраняется.

Что вы сделали, так это вставили объект, который уже был в БД.

0 голосов
/ 05 марта 2019

Для общего интереса к моему коду существует недостаток.Я забыл строку кода, которая объединяет отношения между родителем и ребенком:

allegato.setMessaggi(messaggio);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...