2016-07-27 6 views
0

Ich versuche, ein JpaRepository zu verwenden, um ein Objekt aus der Datenbank durch seine ID zu bekommen und einige Probleme zu haben. Es ist eine Entität mit einer eingebetteten ID.JpaRepository kann Objekt mit EmbeddedID nicht finden

Ich versuche, die Objekt zwei verschiedene Arten zu erhalten:

  1. Mit der benannten Abfrage (findById)
  2. Unter Anwendung des Verfahrens in SowServiceImpl

Die Ausnahme, die ich bekommen, wenn sie versuchen, Get it mit der benannten Methode ist:

@Override 
public SowDocument getById(int i) { 
    SowDocument wow = sowRepository.findById(i); 
    if (wow == null) { 
     System.out.println("NULLLLLLLLLLLLLLLL"); 
     return null; 
    } else { 
     return wow; 
    } 
} 

HTTP Status 500 - Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Parameter with that position [1] did not exist; nested exception is java.lang.IllegalArgumentException: Parameter with that position [1] did not exist 
... 
... 
at com.sun.proxy.$Proxy791.findById(Unknown Source) 
at com.**.pricing.web.services.impl.SowServiceImpl.getById(SowServiceImpl.java:61) 
at com.**.pricing.web.controllers.UserController.getSowById(UserController.java:99) 

Und ich bekomme eine NullPointerException wenn Ich versuche immer es die EmbeddedId mit:

@Override 
public SowDocument getById(int i) { 
    SowDocumentPK peek = new SowDocumentPK(); 
    peek.setId(i); 

    SowDocument wow = sowRepository.findOne(peek); 
    if (wow == null) { 
     System.out.println("NULLLLLLLLLLLLLLLL"); 
     return null; 
    } else { 
     return wow; 
    } 
} 

Hier ist das Objekt:

@Entity 
@Table(name = "SowDocument", uniqueConstraints = { 
    @UniqueConstraint(columnNames = {"id"})}) 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "SowDocument.findAll", query = "SELECT s FROM SowDocument s"), 
    @NamedQuery(name = "SowDocument.findById", query = "SELECT s FROM SowDocument s WHERE s.sowDocumentPK.id = :id"), 
    @NamedQuery(name = "SowDocument.findByClientName", query = "SELECT s FROM SowDocument s WHERE s.clientName = :clientName"), 
    @NamedQuery(name = "SowDocument.findByCreationDate", query = "SELECT s FROM SowDocument s WHERE s.creationDate = :creationDate"), 
    @NamedQuery(name = "SowDocument.findByDocumentCreator", query = "SELECT s FROM SowDocument s WHERE s.sowDocumentPK.documentCreator = :documentCreator"), 
    @NamedQuery(name = "SowDocument.findBySowType", query = "SELECT s FROM SowDocument s WHERE s.sowType = :sowType")}) 
public class SowDocument implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @EmbeddedId 
    protected SowDocumentPK sowDocumentPK; 
    @Size(max = 50) 
    @Column(name = "clientName", length = 50) 
    private String clientName; 
    @Size(max = 45) 
    @Column(name = "creationDate", length = 45) 
    private String creationDate; 
    @Lob 
    @Column(name = "data") 
    private byte[] data; 
    @Size(max = 45) 
    @Column(name = "sowType", length = 45) 
    private String sowType; 
    @JoinColumn(name = "documentCreator", referencedColumnName = "id", nullable = false, insertable = false, updatable = false) 
    @ManyToOne(optional = false) 
    private User user; 

    public SowDocument() { 
    } 

    public SowDocument(SowDocumentPK sowDocumentPK) { 
     this.sowDocumentPK = sowDocumentPK; 
    } 

    public SowDocument(int id, int documentCreator) { 
     this.sowDocumentPK = new SowDocumentPK(id, documentCreator); 
    } 

    public SowDocumentPK getSowDocumentPK() { 
     return sowDocumentPK; 
    } 

    public void setSowDocumentPK(SowDocumentPK sowDocumentPK) { 
     this.sowDocumentPK = sowDocumentPK; 
    } 

    public String getClientName() { 
     return clientName; 
    } 

    public void setClientName(String clientName) { 
     this.clientName = clientName; 
    } 

    public String getCreationDate() { 
     return creationDate; 
    } 

    public void setCreationDate(String creationDate) { 
     this.creationDate = creationDate; 
    } 

    public byte[] getData() { 
     return data; 
    } 

    public void setData(byte[] data) { 
     this.data = data; 
    } 

    public String getSowType() { 
     return sowType; 
    } 

    public void setSowType(String sowType) { 
     this.sowType = sowType; 
    } 

    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (sowDocumentPK != null ? sowDocumentPK.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 SowDocument)) { 
      return false; 
     } 
     SowDocument other = (SowDocument) object; 
     if ((this.sowDocumentPK == null && other.sowDocumentPK != null) || (this.sowDocumentPK != null && !this.sowDocumentPK.equals(other.sowDocumentPK))) { 
      return false; 
     } 
     return true; 
    } 


} 

Und hier ist seine Embedded-ID:

@Embeddable 
public class SowDocumentPK implements Serializable { 

    @Basic(optional = false) 
    @Column(name = "id", nullable = false) 
    private int id; 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "documentCreator", nullable = false) 
    private int documentCreator; 

    public SowDocumentPK() { 
    } 

    public SowDocumentPK(int id, int documentCreator) { 
     this.id = id; 
     this.documentCreator = documentCreator; 
    } 

    public int getId() { 
     return id; 
    } 

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

    public int getDocumentCreator() { 
     return documentCreator; 
    } 

    public void setDocumentCreator(int documentCreator) { 
     this.documentCreator = documentCreator; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (int) id; 
     hash += (int) documentCreator; 
     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 SowDocumentPK)) { 
      return false; 
     } 
     SowDocumentPK other = (SowDocumentPK) object; 
     if (this.id != other.id) { 
      return false; 
     } 
     return this.documentCreator == other.documentCreator; 
    } 


} 

Hier ist der Code für die SowRepository:

public interface SowRepository extends JpaRepository<SowDocument, Serializable> { 

    SowDocument findById(int i); 

} 

Hier ist die Code für die SowService:

@Service 
public class SowServiceImpl implements SowService { 

    @Autowired 
    private SowRepository sowRepository; 

    @Override 
    public void save(SowDocument sow) { 
     sowRepository.save(sow); 
    } 

    @Override 
    public Collection<SowDocument> getAll() { 
     return sowRepository.findAll(); 
    } 

    @Override 
    public SowDocument getById(int i) { 
     SowDocumentPK peek = new SowDocumentPK(); 
     peek.setId(i); 
     return sowRepository.findOne(i); 
    } 


} 

Meine Vermutung ist, dass ich die Zuordnung irgendwie habe (s) falsch zwischen SowDocument/SowDocumentPK oder sind falsch zu verstehen, wie die JpaRepository zu verwenden.

+0

'ShowDocumentPK' hat zwei Felder, aber Sie erstellen' SowDocumentPK peek = new SowDocumentPK(); peek.setId (i); 'und übergeben als Primärschlüssel. Ist es Absicht? – ujulu

+0

Muss ich BOTH-Felder angeben, wenn ich nur ein Objekt mit einer eigenen ID und nicht mit dem vollständigen Composite erhalten möchte? – Zeratas

+0

Ich versuchte zu erklären, wie man es in der Antwort unten verwendet. Schau, ob es dir hilft; Ansonsten, lassen Sie mich einen Kommentar. – ujulu

Antwort

1

Ich denke, Sie verwenden SpringData JPA. Wenn dies richtig ist, schauen, wie die CrudRepository, die den Supertyp JpaRepostory Schnittstelle ist definiert:

public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { 
    ... 
    T findOne(ID id); 
    ... 
} 

Und Sie erweitern diese Schnittstelle als (btw sollten Sie die Implementierung auch gebucht haben):

public interface SowRepository extends JpaRepository<SowDocument, Serializable> { 
    SowDocument findById(int i); 
} 

Die findById(int i) Methode ist in keine der Schnittstellen in der JpaRepository Typhierarchie definiert, was bedeutet, dass es Ihre eigene Erweiterung ist.

Auf der anderen Seite haben Sie keine Entität mit einer ID des Typs int. Der Typ der ID Ihrer Entität ist als Typ ShowDocumentPK definiert, der aus zwei Feldern besteht.

So sollte Ihr Repository Definition wie folgt aussehen:

public interface SowRepository extends JpaRepository<SowDocument, ShowDocumentPK> { 
    SowDocument findById(ShowDocumentPK id); 
} 

und implementieren die Methode findById() selbst (oder verwenden Sie die offizielle Implementierungsklasse des JpaRepository, das heißt SimpleJpaRepository).

Und dann sollten Sie eine Instanz von ShowDocumentPK und übergeben sie an die findById() Verfahren, zum Beispiel erstellen:

SowDocumentPK peek = new SowDocumentPK(); 
peek.setId(1); 
peek.setDocumentCreator(100); 

SowDocument wow = sowRepository.findById(peek); 

Fazit: Ihre ID ist nicht vom Typ int und findById(int) ist nicht die Art und Weise, wie zu implementieren in Ihrem Fall.

Hoffe das gibt Ihnen eine Idee, wie Sie es richtig implementieren.

+0

Ich habe die findById selbst gemacht. Ich habe in CRUDRepository wie Sie gesagt, bevor Sie es gesagt haben und fand die gleiche Schlussfolgerung in meinem eigenen War in der Lage, es jetzt mit einer NamedQuery zu arbeiten. – Zeratas