Java JPA merge()只更新一些字段。其他更改未被识别
这是我的第一篇文章。所以,我希望这个问题是令人兴奋的。 我有一个java程序,它使用Swing+JPA来处理 PostgreSQL数据库。我使用EclipseLink JPA 2.0作为我的 持久性提供者。我的实体类是自动创建的 由Netbeans 7.2.1生成 我面临的问题是:在更新过程中,我改变了四个 使用find()检索对象的字段,然后使用 merge()更新数据库中的对象。三个 表中识别并更新了四项变更, 但其中一个没有更新 我尝试了几种方法来解决这个问题:我尝试更改与持久化单元的同步策略相关的选项,更改代码中的行位置(随着其他字段的更新),我还尝试使用注释@Basic(optional=false)作为实体类字段的前缀。。我的任何一次尝试都成功了 下面是我的实体类(Senha.java)的代码: 当我在数据库中查看时,字段Status Hchamada、Nchamadas被更新,但是字段Painel(布尔类型)没有更新。下面我提供了JPA/EclipseLink的日志摘录:Java JPA merge()只更新一些字段。其他更改未被识别,java,hibernate,jpa,merge,persistence,Java,Hibernate,Jpa,Merge,Persistence,这是我的第一篇文章。所以,我希望这个问题是令人兴奋的。 我有一个java程序,它使用Swing+JPA来处理 PostgreSQL数据库。我使用EclipseLink JPA 2.0作为我的 持久性提供者。我的实体类是自动创建的 由Netbeans 7.2.1生成 我面临的问题是:在更新过程中,我改变了四个 使用find()检索对象的字段,然后使用 merge()更新数据库中的对象。三个 表中识别并更新了四项变更, 但其中一个没有更新 我尝试了几种方法来解决这个问题:我尝试更改与持久化单元的同步
**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。然后:
在我尝试在同一事务中使用remove()和merge()之前,它不起作用。根据实现的不同,EclipseLink在您的情况下,JPA将始终插入所有映射列,并且只更新已更改的列。如果需要其他操作,则可以使用API、SQL或存储过程自定义用于这些操作的查询 您可以使用Hibernate dynamicInsert和DynamicCupDate修改此行为,但不能使用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**
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();