Home > Back-end >  An instance of a null PK has been incorrectly provided for this find operation
An instance of a null PK has been incorrectly provided for this find operation

Time:02-03

I'm using Eclipselink to persist data to MySQL database and when I call the create method, it give me the error:

An instance of a null PK has been incorrectly provided for this find operation

I've searched on other questions here, but none of them solved my problem. I have a class Autor and a class Filme. Both have the ID field as AUTO INCREMENT and the table Filme have the foreign key referencing to Autor.id_autor.

Here is the code of my database:


CREATE TABLE `autor` (
  `id_autor` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(100) NOT NULL,
  PRIMARY KEY (`id_autor`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

CREATE TABLE `filme` (
  `id_filme` int(11) NOT NULL AUTO_INCREMENT,
  `id_autor` int(11) NOT NULL,
  `nome` varchar(100) NOT NULL,
  PRIMARY KEY (`id_filme`),
  KEY `fk_flme_ator_idx` (`id_autor`),
  CONSTRAINT `fk_flme_ator` FOREIGN KEY (`id_autor`) REFERENCES `autor` (`id_autor`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

And the Java classes:

Autor.java

package model;

import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@Entity
@Table(name = "autor")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Autor.findAll", query = "SELECT a FROM Autor a"),
    @NamedQuery(name = "Autor.findByIdAutor", query = "SELECT a FROM Autor a WHERE a.idAutor = :idAutor"),
    @NamedQuery(name = "Autor.findByNome", query = "SELECT a FROM Autor a WHERE a.nome = :nome")})
public class Autor implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id_autor")
    private Integer idAutor;
    @Basic(optional = false)
    @Column(name = "nome")
    private String nome;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idAutor")
    private Collection<Filme> filmeCollection;

    public Autor() {
    }

    public Autor(Integer idAutor) {
        this.idAutor = idAutor;
    }

    public Autor(Integer idAutor, String nome) {
        this.idAutor = idAutor;
        this.nome = nome;
    }

    public Integer getIdAutor() {
        return idAutor;
    }

    public void setIdAutor(Integer idAutor) {
        this.idAutor = idAutor;
    }

    public String getNome() {
        return nome;
    }

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

    @XmlTransient
    public Collection<Filme> getFilmeCollection() {
        return filmeCollection;
    }

    public void setFilmeCollection(Collection<Filme> filmeCollection) {
        this.filmeCollection = filmeCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash  = (idAutor != null ? idAutor.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Autor)) {
            return false;
        }
        Autor other = (Autor) object;
        if ((this.idAutor == null && other.idAutor != null) || (this.idAutor != null && !this.idAutor.equals(other.idAutor))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return nome;
    }
    
}

Filme.java

package model;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table(name = "filme")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Filme.findAll", query = "SELECT f FROM Filme f"),
    @NamedQuery(name = "Filme.findByIdFilme", query = "SELECT f FROM Filme f WHERE f.idFilme = :idFilme"),
    @NamedQuery(name = "Filme.findByNome", query = "SELECT f FROM Filme f WHERE f.nome = :nome")})
public class Filme implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id_filme")
    private Integer idFilme;
    @Basic(optional = false)
    @Column(name = "nome")
    private String nome;
    @JoinColumn(name = "id_autor", referencedColumnName = "id_autor")
    @ManyToOne(optional = false)
    private Autor idAutor;

    public Filme() {
    }

    public Filme(Integer idFilme) {
        this.idFilme = idFilme;
    }

    public Filme(Integer idFilme, String nome) {
        this.idFilme = idFilme;
        this.nome = nome;
    }

    public Integer getIdFilme() {
        return idFilme;
    }

    public void setIdFilme(Integer idFilme) {
        this.idFilme = idFilme;
    }

    public String getNome() {
        return nome;
    }

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

    public Autor getIdAutor() {
        return idAutor;
    }

    public void setIdAutor(Autor idAutor) {
        this.idAutor = idAutor;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash  = (idFilme != null ? idFilme.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Filme)) {
            return false;
        }
        Filme other = (Filme) object;
        if ((this.idFilme == null && other.idFilme != null) || (this.idFilme != null && !this.idFilme.equals(other.idFilme))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return nome;
    }

}

Main.java:

public static void main(String[] args) {

        EntityManagerFactory emf = null;
        if (emf == null) {
            emf = Persistence.createEntityManagerFactory("Estudos_JPAPU");
        }
        
        Autor a = new Autor();
        a.setNome("Autor 1");
        a.setFilmeCollection(new ArrayList());
        
        Filme f = new Filme();
        f.setNome("Filme 1");
        f.setIdAutor(a);

        a.getFilmeCollection().add(f);
                
        new AutorJpaController(emf).create(a);

    }

EDIT

AutorJpaController.java

import controller.exceptions.IllegalOrphanException;
import controller.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import model.Filme;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import model.Autor;

public class AutorJpaController implements Serializable {

    public AutorJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Autor autor) {
        if (autor.getFilmeCollection() == null) {
            autor.setFilmeCollection(new ArrayList<Filme>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Collection<Filme> attachedFilmeCollection = new ArrayList<Filme>();
            for (Filme filmeCollectionFilmeToAttach : autor.getFilmeCollection()) {
                filmeCollectionFilmeToAttach = em.getReference(filmeCollectionFilmeToAttach.getClass(), filmeCollectionFilmeToAttach.getIdFilme());
                attachedFilmeCollection.add(filmeCollectionFilmeToAttach);
            }
            autor.setFilmeCollection(attachedFilmeCollection);
            em.persist(autor);
            for (Filme filmeCollectionFilme : autor.getFilmeCollection()) {
                Autor oldIdAutorOfFilmeCollectionFilme = filmeCollectionFilme.getIdAutor();
                filmeCollectionFilme.setIdAutor(autor);
                filmeCollectionFilme = em.merge(filmeCollectionFilme);
                if (oldIdAutorOfFilmeCollectionFilme != null) {
                    oldIdAutorOfFilmeCollectionFilme.getFilmeCollection().remove(filmeCollectionFilme);
                    oldIdAutorOfFilmeCollectionFilme = em.merge(oldIdAutorOfFilmeCollectionFilme);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Autor autor) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Autor persistentAutor = em.find(Autor.class, autor.getIdAutor());
            Collection<Filme> filmeCollectionOld = persistentAutor.getFilmeCollection();
            Collection<Filme> filmeCollectionNew = autor.getFilmeCollection();
            List<String> illegalOrphanMessages = null;
            for (Filme filmeCollectionOldFilme : filmeCollectionOld) {
                if (!filmeCollectionNew.contains(filmeCollectionOldFilme)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Filme "   filmeCollectionOldFilme   " since its idAutor field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Collection<Filme> attachedFilmeCollectionNew = new ArrayList<Filme>();
            for (Filme filmeCollectionNewFilmeToAttach : filmeCollectionNew) {
                filmeCollectionNewFilmeToAttach = em.getReference(filmeCollectionNewFilmeToAttach.getClass(), filmeCollectionNewFilmeToAttach.getIdFilme());
                attachedFilmeCollectionNew.add(filmeCollectionNewFilmeToAttach);
            }
            filmeCollectionNew = attachedFilmeCollectionNew;
            autor.setFilmeCollection(filmeCollectionNew);
            autor = em.merge(autor);
            for (Filme filmeCollectionNewFilme : filmeCollectionNew) {
                if (!filmeCollectionOld.contains(filmeCollectionNewFilme)) {
                    Autor oldIdAutorOfFilmeCollectionNewFilme = filmeCollectionNewFilme.getIdAutor();
                    filmeCollectionNewFilme.setIdAutor(autor);
                    filmeCollectionNewFilme = em.merge(filmeCollectionNewFilme);
                    if (oldIdAutorOfFilmeCollectionNewFilme != null && !oldIdAutorOfFilmeCollectionNewFilme.equals(autor)) {
                        oldIdAutorOfFilmeCollectionNewFilme.getFilmeCollection().remove(filmeCollectionNewFilme);
                        oldIdAutorOfFilmeCollectionNewFilme = em.merge(oldIdAutorOfFilmeCollectionNewFilme);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = autor.getIdAutor();
                if (findAutor(id) == null) {
                    throw new NonexistentEntityException("The autor with id "   id   " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Autor autor;
            try {
                autor = em.getReference(Autor.class, id);
                autor.getIdAutor();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The autor with id "   id   " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Filme> filmeCollectionOrphanCheck = autor.getFilmeCollection();
            for (Filme filmeCollectionOrphanCheckFilme : filmeCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Autor ("   autor   ") cannot be destroyed since the Filme "   filmeCollectionOrphanCheckFilme   " in its filmeCollection field has a non-nullable idAutor field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(autor);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Autor> findAutorEntities() {
        return findAutorEntities(true, -1, -1);
    }

    public List<Autor> findAutorEntities(int maxResults, int firstResult) {
        return findAutorEntities(false, maxResults, firstResult);
    }

    private List<Autor> findAutorEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Autor.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Autor findAutor(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Autor.class, id);
        } finally {
            em.close();
        }
    }

    public int getAutorCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Autor> rt = cq.from(Autor.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}

FilmeJpaController.java

import controller.exceptions.NonexistentEntityException;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import model.Autor;
import model.Filme;

public class FilmeJpaController implements Serializable {

    public FilmeJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Filme filme) {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Autor idAutor = filme.getIdAutor();
            if (idAutor != null) {
                idAutor = em.getReference(idAutor.getClass(), idAutor.getIdAutor());
                filme.setIdAutor(idAutor);
            }
            em.persist(filme);
            if (idAutor != null) {
                idAutor.getFilmeCollection().add(filme);
                idAutor = em.merge(idAutor);
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Filme filme) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Filme persistentFilme = em.find(Filme.class, filme.getIdFilme());
            Autor idAutorOld = persistentFilme.getIdAutor();
            Autor idAutorNew = filme.getIdAutor();
            if (idAutorNew != null) {
                idAutorNew = em.getReference(idAutorNew.getClass(), idAutorNew.getIdAutor());
                filme.setIdAutor(idAutorNew);
            }
            filme = em.merge(filme);
            if (idAutorOld != null && !idAutorOld.equals(idAutorNew)) {
                idAutorOld.getFilmeCollection().remove(filme);
                idAutorOld = em.merge(idAutorOld);
            }
            if (idAutorNew != null && !idAutorNew.equals(idAutorOld)) {
                idAutorNew.getFilmeCollection().add(filme);
                idAutorNew = em.merge(idAutorNew);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = filme.getIdFilme();
                if (findFilme(id) == null) {
                    throw new NonexistentEntityException("The filme with id "   id   " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Filme filme;
            try {
                filme = em.getReference(Filme.class, id);
                filme.getIdFilme();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The filme with id "   id   " no longer exists.", enfe);
            }
            Autor idAutor = filme.getIdAutor();
            if (idAutor != null) {
                idAutor.getFilmeCollection().remove(filme);
                idAutor = em.merge(idAutor);
            }
            em.remove(filme);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Filme> findFilmeEntities() {
        return findFilmeEntities(true, -1, -1);
    }

    public List<Filme> findFilmeEntities(int maxResults, int firstResult) {
        return findFilmeEntities(false, maxResults, firstResult);
    }

    private List<Filme> findFilmeEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Filme.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Filme findFilme(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Filme.class, id);
        } finally {
            em.close();
        }
    }

    public int getFilmeCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Filme> rt = cq.from(Filme.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}

CodePudding user response:

For create, depending on how you want to handle the object graph, you'll need to look at the references within that graph and handle them appropriately:

public void create(Filme filme) {
    EntityManager em = null;
    try {
        em = getEntityManager();
        em.getTransaction().begin();
        Autor autor = filme.getIdAutor();
        if (autor != null) {
            Integer autorId = autor.getId();
          if (autorId == null) {
            em.persist(autor);
          } else {
            //if this has an id, let this call throw an error if it doesn't exist in the database
            autor = em.getReference(idAutor.getClass(), autorId);
            filme.setIdAutor(autor);
            //autor is managed already, so no need to call merge
            autor.getFilmeCollection().add(filme);
        }
        em.persist(filme);
        em.getTransaction().commit();
    } finally {
        if (em != null) {
            em.close();
        }
    }
}

The above allows you to decide what to do when you encounter an Autor instance being referenced from the Filme. Calling Persist explicitly on it though will cause that persist call to cascade over the filmeCollection relationship, so anything referenced in there will also have persist called on it - something to watch out for if this isn't a blank/empty instance.

  •  Tags:  
  • Related