Jpa 具有枚举值的ObjectDB更新查询不可查询
使用更新查询更新枚举字段时遇到一些困难。似乎每当我用新值更新枚举字段时,更新后的值就不可能与新查询匹配。更新查询适用于其他数据类型,但不适用于枚举 我已尝试关闭EntityManager、EntityManager工厂和应用程序,但由于某些原因,该字段在其新状态下无法匹配 下面是我正在使用的一个测试,“db”实例只是一个类,它为EntityManager处理实例化、关闭和事务Jpa 具有枚举值的ObjectDB更新查询不可查询,jpa,objectdb,Jpa,Objectdb,使用更新查询更新枚举字段时遇到一些困难。似乎每当我用新值更新枚举字段时,更新后的值就不可能与新查询匹配。更新查询适用于其他数据类型,但不适用于枚举 我已尝试关闭EntityManager、EntityManager工厂和应用程序,但由于某些原因,该字段在其新状态下无法匹配 下面是我正在使用的一个测试,“db”实例只是一个类,它为EntityManager处理实例化、关闭和事务 @Test public void test() { db.execute(em -> em.create
@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!
}
@测试
公开无效测试(){
执行(em->em.createQuery(“更新大气设置=:设置,其中id=:id”,Atmosphere.class)
.setParameter(“设置”,大气。设置。海岸)
.setParameter(“id”,atmosphere1.getId()).executeUpdate());
List results=db.retrieve(em->em.createQuery(“从大气中选择,其中id=:id”,Atmosphere.class))
.setParameter(“id”,atmosphere1).getResultList());
assertFalse(results.isEmpty());//通过
assertEquals(Atmosphere.Setting.coast,results.get(0.getSetting());//通过,记录被更新!
results=db.retrieve(em->em.createQuery(“从大气中选择,设置=:设置”,大气.class)
.setParameter(“设置”,大气。设置。海岸)
.getResultList());
assertFalse(results.isEmpty());//失败,没有结果!
}
我也检查了explorer工具中的行,可以看到它已更新,但仍然无法查询它
唯一有效的方法是使用EntityManager.merge()
更新记录
编辑:发现只有在实体的枚举字段上使用
@Enumerated(EnumType.STRING)
时才会出现问题。删除此选项可修复此问题(在objectdb 2.7.6中)。以下代码似乎工作正常:
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)
时才会出现问题。据我所知,唯一的解决办法是删除注释,使其默认为有序类型持久化(在objectdb 2.7.6中)。使用更新查询更新基于字符串的枚举字段时出现问题,这是正确的。这是因为ObjectDB始终将参数视为序号
一个简单的解决方法是将字段显式设置为字符串:
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 }
}
谢谢你的出发点。经过一些实验,我发现只有在实体的字段上使用
@Enumerated(EnumType.STRING)
时才会出现问题。