【问题标题】:ObjectDB update query with enum value is not queryable具有枚举值的 ObjectDB 更新查询不可查询
【发布时间】:2019-04-08 15:16:39
【问题描述】:

我在使用更新查询更新枚举字段时遇到了一些困难。似乎每当我用新值更新枚举字段时,更新的值不可能匹配新查询。更新查询适用于其他数据类型,但不适用于枚举。

我已尝试关闭 EntityManager、EntityManagerFactory、应用程序,但由于某种原因,无法在新状态下匹配该字段。

下面是我正在使用的测试,其中“db”实例只是一个处理 EntityManager 的实例化、关闭和事务的类。

@Test
public void test() {
    db.execute(em -> em.createQuery("UPDATE Atmosphere SET setting = :setting WHERE id=:id", Atmosphere.class)
            .setParameter("setting", Atmosphere.Setting.coast)
            .setParameter("id", atmosphere1.getId()).executeUpdate());

    List<Atmosphere> results = db.retrieve(em -> em.createQuery("SELECT FROM Atmosphere WHERE id = :id", Atmosphere.class)
        .setParameter("id", atmosphere1).getResultList());
    assertFalse(results.isEmpty()); // passes
    assertEquals(Atmosphere.Setting.coast, results.get(0).getSetting()); // passes, the record is updated!

    results = db.retrieve(em -> em.createQuery("SELECT FROM Atmosphere WHERE setting = :setting", Atmosphere.class)
            .setParameter("setting", Atmosphere.Setting.coast)
            .getResultList());
    assertFalse(results.isEmpty()); // fails, no results!
}

我也在资源管理器工具中检查了该行,可以看到它已更新,但我仍然无法查询。

似乎唯一可行的方法是使用 EntityManager.merge() 更新记录。

编辑:原来只有在实体的枚举字段上使用@Enumerated(EnumType.STRING) 时才会出现问题。删除它可以解决问题(在 objectdb 2.7.6 中)。

【问题讨论】:

    标签: jpa objectdb


    【解决方案1】:

    经过一些实验,我发现只有在使用@Enumerated(EnumType.STRING) 时才会出现问题。据我所知,唯一的解决方法是删除注释以默认为序数类型持久性(在 objectdb 2.7.6 中)。

    【讨论】:

      【解决方案2】:

      您说得对,使用 UPDATE 查询更新基于 STRING 的枚举字段存在问题。这是因为 ObjectDB 始终将参数视为 ORDINAL。

      一个简单的解决方法是将字段显式设置为字符串:

      import javax.persistence.*;
      
      public class T53151410
      {
          public static void main(String[] args)
          {
              EntityManagerFactory emf = Persistence.createEntityManagerFactory("objectdb:db.tmp;drop");
      
              EntityManager em = emf.createEntityManager();
      
              em.getTransaction().begin();
              em.persist(new MyEntity());
              em.getTransaction().commit();
      
              em.getTransaction().begin();
              System.out.println(
                  em.createQuery("UPDATE MyEntity SET color = :color")
                      .setParameter("color", Color.RED.name()).executeUpdate()
              ); 
              em.getTransaction().commit();
      
              System.out.println(
                  em.createQuery("SELECT FROM MyEntity WHERE color = :color")
                      .setParameter("color", Color.RED).getResultList().size()
              );
      
              em.close();
              emf.close();
          }
      
          @Entity
          private static class MyEntity
          {
              @Enumerated(EnumType.STRING) Color color;
          }
      
          private static enum Color { RED, GREEN, BLUE }
      }
      

      【讨论】:

        【解决方案3】:

        以下代码似乎可以正常工作:

            import javax.persistence.*;
        
            public class T53151410 {
                public static void main(String[] args) {
        
                    EntityManagerFactory emf = 
                        Persistence.createEntityManagerFactory(
                            "objectdb:db.tmp;drop");
                    EntityManager em = emf.createEntityManager();
        
                    em.getTransaction().begin();
                    em.persist(new MyEntity());
                    em.getTransaction().commit();
        
                    em.getTransaction().begin();
                    System.out.println(
                        em.createQuery("UPDATE MyEntity SET color = :color")
                            .setParameter("color", Color.RED).executeUpdate()
                    ); 
                    em.getTransaction().commit();
        
                    System.out.println(
                        em.createQuery("SELECT FROM MyEntity WHERE color = :color")
                            .setParameter("color", Color.RED).getResultList().size()
                    );
        
                    em.close();
                    emf.close();
                }
        
                @Entity
                private static class MyEntity {
                    Color color;
                }
        
                private static enum Color { RED, GREEN, BLUE }
            }
        }
        

        【讨论】:

        • 感谢您的起点。经过一些实验,我发现只有在实体字段上使用@Enumerated(EnumType.STRING)时才会出现问题。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-09
        • 2014-12-21
        • 2013-05-28
        • 1970-01-01
        • 2017-03-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多