Ich habe ein Java-Programm, das Swing+JPA verwendet, um mit einer
PostgreSQL-Datenbank zu arbeiten. Ich verwende EclipseLink JPA 2.0 als meinen
Persistenzanbieter. Meine Entitätsklasse wurde automatisch
von Netbeans 7.2.1 generiert
Das Problem, mit dem ich konfrontiert bin, ist: Während einer Aktualisierung ändere ich vier
Felder eines Objekts, das mit find() abgerufen wurde, und verwende dann
merge(), um das Objekt in der Datenbank zu aktualisieren. Drei von
vier Änderungen werden in der Tabelle erkannt und aktualisiert,
eine davon wird jedoch nicht aktualisiert.
Ich habe mehrere Dinge versucht, um dieses Problem zu umgehen: Ich habe versucht, die Optionen im Zusammenhang mit der Synchronisierungsstrategie meiner persistenten Einheit zu ändern, die Zeilenposition im Code zu ändern (da andere Felder aktualisiert werden), ich habe auch versucht, dem Entity Class-Feld die Annotation @Basic (optional = false) voranzustellen. Jeder meiner Versuche hat funktioniert.
Hier ist der Code meiner Entity Class (Senha.java):
Code: Select all
package model;
import java.io.Serializable;
import java.util.Date;
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.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Diego Dias
*/
@Entity
@Table(name = "senha")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Senha.findAll", query = "SELECT s FROM Senha s"),
@NamedQuery(name = "Senha.findById", query = "SELECT s FROM Senha s WHERE s.id = :id"),
@NamedQuery(name = "Senha.findByGuiche", query = "SELECT s FROM Senha s WHERE s.guiche = :guiche"),
@NamedQuery(name = "Senha.findByStatus", query = "SELECT s FROM Senha s WHERE s.status = :status"),
@NamedQuery(name = "Senha.findByHchamada", query = "SELECT s FROM Senha s WHERE s.hchamada = :hchamada"),
@NamedQuery(name = "Senha.findByAtendente", query = "SELECT s FROM Senha s WHERE s.atendente = :atendente"),
@NamedQuery(name = "Senha.findByHcriacao", query = "SELECT s FROM Senha s WHERE s.hcriacao = :hcriacao"),
@NamedQuery(name = "Senha.findByDtcriacao", query = "SELECT s FROM Senha s WHERE s.dtcriacao = :dtcriacao"),
@NamedQuery(name = "Senha.findByNumeracao", query = "SELECT s FROM Senha s WHERE s.numeracao = :numeracao"),
@NamedQuery(name = "Senha.findByNchamadas", query = "SELECT s FROM Senha s WHERE s.nchamadas = :nchamadas"),
@NamedQuery(name = "Senha.findByPainel", query = "SELECT s FROM Senha s WHERE s.painel = :painel"),
@NamedQuery(name = "Senha.findMaxNumeracaoByDtcriacao", query = "SELECT MAX(s.numeracao) FROM Senha s WHERE s.dtcriacao = :dtcriacao"),
@NamedQuery(name = "Senha.findByStatusAndHchamadaAndHcriacao", query = "SELECT s FROM Senha s WHERE s.status = :status AND s.hchamada = :hcriacao")})
public class Senha implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Column(name = "guiche")
private String guiche;
@Column(name = "status")
private Character status;
@Column(name = "hchamada")
@Temporal(TemporalType.TIME)
private Date hchamada;
@Column(name = "atendente")
private Integer atendente;
@Column(name = "hcriacao")
@Temporal(TemporalType.TIME)
private Date hcriacao;
@Column(name = "dtcriacao")
@Temporal(TemporalType.DATE)
private Date dtcriacao;
@Column(name = "numeracao")
private Integer numeracao;
@Column(name = "nchamadas")
private Integer nchamadas;
@Column(name = "painel")
private Boolean painel;
public Senha() {
}
public Senha(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getGuiche() {
return guiche;
}
public void setGuiche(String guiche) {
this.guiche = guiche;
}
public Character getStatus() {
return status;
}
public void setStatus(Character status) {
this.status = status;
}
public Date getHchamada() {
return hchamada;
}
public void setHchamada(Date hchamada) {
this.hchamada = hchamada;
}
public Integer getAtendente() {
return atendente;
}
public void setAtendente(Integer atendente) {
this.atendente = atendente;
}
public Date getHcriacao() {
return hcriacao;
}
public void setHcriacao(Date hcriacao) {
this.hcriacao = hcriacao;
}
public Date getDtcriacao() {
return dtcriacao;
}
public void setDtcriacao(Date dtcriacao) {
this.dtcriacao = dtcriacao;
}
public Integer getNumeracao() {
return numeracao;
}
public void setNumeracao(Integer numeracao) {
this.numeracao = numeracao;
}
public Integer getNchamadas() {
return nchamadas;
}
public void setNchamadas(Integer nchamadas) {
this.nchamadas = nchamadas;
}
public Boolean getPainel() {
return painel;
}
public void setPainel(Boolean painel) {
this.painel = painel;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Senha)) {
return false;
}
Senha other = (Senha) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "model.Senha[ id=" + id + " ]";
}
}
Code: Select all
EntityManagerFactory emf = ctrlCreateEntityManager();
EntityManager em = emf.createEntityManager();
...
current = em.find(Senha.class, getCurrentId());
if (current.getStatus().equals('W')) {
em.getTransaction().begin();
current.setStatus(current.getNchamadas() >= 2 ? 'L' : current.getStatus());
current.setHchamada(Calendar.getInstance().getTime());
current.setNchamadas(current.getNchamadas() + 1);
current.setPainel(true);
em.merge(current);
em.getTransaction().commit();
frame.getLbNumeroSenha().setText(formatSenha(current.getNumeracao()));
}
...
em.close();
emf.close();
Code: Select all
**begin transaction**
**[EL Fine]**:
Thread(Thread[AWT-EventQueue-1,4,file:...-threadGroup])--UPDATE senha SET
hchamada = ?, nchamadas = ? WHERE (id = ?)
bind => [02:15:49, 2, 4]
**[EL Finer]**:
Thread(Thread[AWT-EventQueue-1,4,file:...-threadGroup])
**commit transaction**
Code: Select all
EntityManagerFactory emf = ctrlCreateEntityManager();
EntityManager em = emf.createEntityManager();
...
current = em.find(Senha.class, getCurrentId());
if (current.getStatus().equals('W')) {
em.getTransaction().begin();
current.setStatus(current.getNchamadas() >= 2 ? 'L' : current.getStatus());
current.setHchamada(Calendar.getInstance().getTime());
current.setNchamadas(current.getNchamadas() + 1);
if (current.getPainel()) {
System.out.println("Painel is already true");
}
current.setPainel(true);
em.merge(current);
em.getTransaction().commit();
frame.getLbNumeroSenha().setText(formatSenha(current.getNumeracao()));
}
...
em.close();
emf.close();
- Ich habe nicht verstanden, warum dieses Update beim Abrufen der Entität nicht erkannt wird.
- Wie kann ich JPA zwingen, alle Felder zu aktualisieren (auch die, die sich nicht ändern)?
Gerade als ich diese Nachricht gepostet habe, wurde mir klar eine mögliche Lösung (nicht so gut). Ändern Sie den Code vor der Aktualisierung, um die Entität aus der Datenbank zu entfernen (durch einen Commit), und starten Sie dann eine andere Transaktion, um das Objekt zu aktualisieren. Es geht darum, das Objekt zu entfernen und erneut beizubehalten. Es funktioniert.
Vorher habe ich versucht, „remove()“ und „merge()“ innerhalb derselben Transaktion zu verwenden, aber es hat nicht funktioniert.
Mobile version