java只修改变的字段_java – JPA merge()仅更新某些字段.其他变更...

这是我的第一篇文章.所以,我希望这个问题令人兴奋.

我有一个使用Swing JPA来处理的java程序

PostgreSQL数据库.我使用EclipseLink JPA 2.0作为我的

持久性提供者.我的实体类是自动的

由Netbeans 7.2.1生成

我面临的问题是:在更新过程中,我改变了四个

使用find()检索对象的字段,然后我使用

merge()更新数据库中的对象.三个

表中识别并更新了四个更改,

但其中一个没有更新.

我尝试了几个方法来解决这个问题:我尝试更改与持久单元的同步策略相关的选项,更改代码中的行位置(因为其他字段已更新),我还尝试在实体类字段前添加前缀注释@Basic(可选= false)..我的任何一个尝试都有效.

这是我的实体类(Senha.java)的代码:

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 <= :hchamada AND s.hcriacao >= :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 + " ]";

}

}

以下是更新我的对象的方法的相关代码.里面的代码……不会影响对象.

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();

当我查看数据库时,状态Hchamada,Nchamadas字段已更新,但字段Painel(类型为boolean)未更新.接下来我将介绍JPA / EclipseLink的日志记录摘录:

**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**

查看代码,我在更改值之前放置了一个if,以查看JPA管理的实体是否已经设置了我想要设置的值.这是修改后的代码:

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();

当我运行代码时,我得到的消息表明我的实体已经设置了我想在数据库中写入的值.所以,我认为如果JPA / EclipseLink相对于它管理的实体类没有改变,它就不会更新该值.但是,在运行代码之前,我手动将数据库字段painel更新为false.然后:

>我不明白为什么在检索实体时无法识别此更新.

>如何强制JPA更新所有字段(即使不更改)?

可能的(不是那么好)解决方案:

就在发布此消息的那一刻,我意识到了一个可能的解决方案(不太好).在更新之前修改代码以从数据库中删除实体(给出提交),然后启动其他事务,更新对象.它是,再次删除和持久化对象.有用.

在我尝试在同一个事务中使用remove()和merge()之前,它没有用.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值