Amigos a parada é o seguinte estou com dificuldade de salvar um relacionamento muito para muitos.
As tabelas principais salva normal o problema é na tabela que relaciona as duas.
O erro é o seguinte:
javax.servlet.ServletException: org.hibernate.PropertyValueException: not-null property references a null or transient value: entidades.AbastecimentosReservatoriosMov.idAbastecimentoFK
Pelo que conta é o abastecimento que ta vindo null mas ja debuguei e ele tem objeto nele.
Outra coisa que tenho a colocar é que nao sei uma forma mais “profissional” e menos POG de fazer o relacionamento na tabela AbastecimentosReservatoriosMov que nao seja Iterando e setando os objetos. Alguém pode me ajudar?
Segue abaixo o JPA e o codigo que salva:
@Entity
@Table(name = "Abastecimento")
public class Abastecimento implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idAbastecimento")
private Integer idAbastecimento;
@Column(name = "data")
@Temporal(TemporalType.DATE)
private Date data;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idAbastecimentoFK")
private Collection<AbastecimentosReservatoriosMov> abastecimentosReservatoriosMovCollection;
@Entity
@Table(name = "AbastecimentoReservatoriosMov")
public class AbastecimentoReservatoriosMov implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idAbastecimentoReservatorioMov")
private Integer idAbastecimentoReservatorioMov;
@JoinColumn(name = "idAbastecimento_FK", referencedColumnName = "idAbastecimento")
@ManyToOne(optional = false)
private Abastecimento idAbastecimentoFK;
@JoinColumn(name = "idReservatorioMovimento_FK", referencedColumnName = "idReservatorioMovimento")
@ManyToOne(optional = false)
private Reservatoriosmovimentos idReservatorioMovimentoFK;
@Entity
@Table(name = "reservatoriosmovimentos")
public class Reservatoriosmovimentos implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idReservatorioMovimento")
private Integer idReservatorioMovimento;
@Column(name = "volume")
private Double volume;
@Column(name = "movimentoTipo")
private String movimentoTipo;
@Column(name = "dataMovimento")
@Temporal(TemporalType.DATE)
private Date dataMovimento;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idReservatorioMovimentoFK")
private Collection<AbastecimentosReservatoriosMov> abastecimentosReservatoriosMovCollection;
public void salvarAbastecimento(Abastecimento abastecimento,List<Reservatoriosmovimentos> listaReservatoriosMov) {
// Cria a sessao com o banco e a transacao...
Session session = HibernateUtil.getSession();
Transaction t = session.beginTransaction();
AbastecimentosReservatoriosMov abastecimentosReservatoriosMov = new AbastecimentosReservatoriosMov();
Iterator<Reservatoriosmovimentos> itr = listaReservatoriosMov.iterator();
while (itr.hasNext()) {
Reservatoriosmovimentos reservatorioMovimento = (Reservatoriosmovimentos) itr
.next();
abastecimentoReservatoriosMov.setIdAbastecimentoFK(abastecimento);
abastecimentoReservatoriosMov.setIdReservatorioMovimentoFK(reservatorioMovimento);
session.save(abastecimentosReservatoriosMov); //DÁ PAU AQUI, SE EU COMENTAR ESSA LINHA ELE SALVAA NAS TABELAS PRINCIPAIS session.merge(reservatorioMovimento);
abastecimentosReservatoriosMov = new AbastecimentossReservatoriosMov();
}
session.merge(abastecimento);
t.commit();
}
Alguem pode me ajudar a conseguir salvar nesta terceira tabelas?
kra tenho um relacionamento N-N e fiz diferente, fiz uma 3ª classe onde recebe essas 2 chaves e funciona legal pq ouvi dizer q N-N é complicado msm acertar…
Pois é fiz assim também a minha terceira classe é a AbastecimentoReservatoriosMov é a segunda Entity descrita no meu primeiro post.
Tenho um amigo que disse que sofreu com isso ano passado e desistiu, disso que acha q é algum bug do hibernate, mas duvido muito pois esse tipo de relacionamento é muito importante.
Agora fazer esse “trem” funcionar é uma questão de honra.
Galera depois de bater um pouco a cabeça consegui resolver parcialmente o problema.
Mudei minhas classes de entidades fazendo o relacionamento @many-to-many nas duas tabelas principais e removi a classe que relaciona a duas, ficou assim:
@Entity
@Table(name = "Abastecimento")
public class Abastecimento implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idAbastecimento")
private Integer idAbastecimento;
@Column(name = "data")
@Temporal(TemporalType.DATE)
private Date data;
@ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinTable(name = "AbastecimentosReservatoriosMov",
joinColumns = { @JoinColumn(name = "idAbastecimento_FK", nullable = false,
updatable = false) }, inverseJoinColumns = {
@JoinColumn(name = "idReservatorioMovimento_FK", nullable = false, updatable = false) })
private Set<Reservatoriosmovimentos> idReservatorioMovimentoFK = new HashSet<Reservatoriosmovimentos>(0);
@Entity
@Table(name = "reservatoriosmovimentos")
public class Reservatoriosmovimentos implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idReservatorioMovimento")
private Integer idReservatorioMovimento;
@Column(name = "volume")
private Double volume;
@Column(name = "movimentoTipo")
private String movimentoTipo;
@Column(name = "dataMovimento")
@Temporal(TemporalType.DATE)
private Date dataMovimento;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "AbastecimentosReservatoriosMov",
joinColumns = { @JoinColumn(name = "idReservatorioMovimento_FK", nullable = false,
updatable = false) }, inverseJoinColumns = {
@JoinColumn(name = "idAbastecimento_FK", nullable = false, updatable = false) })
private Set<Abastecimento> idAbastecimentoFK = new HashSet<Abastecimento>(0);
// E O METODO PARA SALVA
public void salvarAbastecimento(Abastecimento abastecimento,
List<Reservatoriosmovimentos> listaReservatoriosMov) {
// Cria a sessao com o banco e a transacao...
Session session = HibernateUtil.getSession();
Transaction t = session.beginTransaction();
Set<Reservatoriosmovimentos> resMov = new HashSet<Reservatoriosmovimentos>();
Iterator<Reservatoriosmovimentos> itr = listaReservatoriosMov
.iterator();
while (itr.hasNext()) {
Reservatoriosmovimentos reservatorioMovimento = (Reservatoriosmovimentos) itr
.next();
resMov.add(reservatorioMovimento);
}
abastecimento.setIdReservatorioMovimentoFK(resMov);
session.merge(abastecimento);
t.commit();
QUANDO PEDI PARA GERAR O BANCO NOVAMENTE ELE FEZ BONITINHO O RELACIONAMENTO CRIANDO A NOVA TABELA DE RELACIONAMENTO, APESAR DE NAO TER CRIADO CHAVE PRIMARIA MESMO NESTE TIPO DE MODELAGEM, A QUAL EU PREFIRO, MAS TUDO BEM.
MAS AGORA A QUESTÃO É A SEGUINTE, PQ ESSE CARA SÓ SALVA O PRIMEIRO DA LISTA E NÃO TODOS?
TIPO ELE SALVA O ABASTECIMENTO MAS NAO DE VARIOS RESERVATORIOS QUE FIZ UM ADD NA ITERAÇÃO DA LISTA, ELE SALVA SOMENTE O PRIMEIRO QUE DA LISTA.