Запрос на обновление ObjectDB со значением enum не запрашивается - PullRequest
0 голосов
/ 05 ноября 2018

У меня возникли трудности с обновлением полей enum с помощью запросов на обновление. Похоже, что всякий раз, когда я обновляю поле перечисления новым значением, обновленное значение невозможно сопоставить для новых запросов. Запрос на обновление отлично работает для других типов данных, но не для перечислений.

Я попытался закрыть 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) в поле enum объекта. Устранение этой проблемы решает проблему (в objectdb 2.7.6).

Ответы [ 3 ]

0 голосов
/ 05 ноября 2018

После некоторых экспериментов я обнаружил, что проблема возникает только при использовании @Enumerated(EnumType.STRING). Насколько я могу судить, единственный обходной путь - удалить аннотацию по умолчанию с порядковым номером (в objectdb 2.7.6).

0 голосов
/ 06 ноября 2018

Вы правы, что существует проблема с обновлением перечисляемого поля на основе STRING с помощью запроса UPDATE. Это потому, что параметр всегда обрабатывается 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 }
}
0 голосов
/ 05 ноября 2018

Следующий код работает нормально:

    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 }
    }
}
...