1

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

我尝试关闭 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 中)。

4

3 回答 3

1

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

于 2018-11-05T20:16:50.010 回答
1

您是对的,使用 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 }
}
于 2018-11-06T02:13:12.627 回答
0

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

    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 }
    }
}
于 2018-11-05T13:45:43.437 回答