JQL sorgum neden eşdeğer CriteriaBuilder sorgusundan farklı bir sonuç döndürüyor?

Aug 17 2020

Dropwizard Hibernate kullanıyorum ve testlerimle ilgili sorunlar yaşıyorum. Bu örneği olabildiğince basitleştirdim. Bir yaratıyorum Foo, güncelliyorum ve sonra getirmeye çalışıyorum. Ham sorgu kullanmak doğru sonucu alır, ancak eşdeğer CriteriaBuilder sorgusu güncellemeyi yakalamaz. Neyi yanlış yapıyorum?

    @Test
    public void testFoo() {
        String id = "12345";

        // Create
        Foo foo = Foo.builder()
            .id(id)
            .name("old-name")
            .build();
        sessionFactory.getCurrentSession().replicate(foo, ReplicationMode.EXCEPTION);

        // Update
        database.inTransaction(() -> {
            CriteriaBuilder cb = sessionFactory.getCurrentSession().getCriteriaBuilder();
            CriteriaUpdate<Foo> update = cb.createCriteriaUpdate(Foo.class);
            Root<Foo> root = update.from(Foo.class);

            update.set(Foo_.name, "new-name");
            update.where(cb.equal(root.get(Foo_.id), id));
            int updated = sessionFactory.getCurrentSession().createQuery(update).executeUpdate();
        });

        // Select
        database.inTransaction(() -> {
            sessionFactory.getCurrentSession().flush(); // Not sure if this matters

            String newName = (String) sessionFactory.getCurrentSession()
                .createQuery("select name from Foo where id=:id")
                .setParameter("id", id)
                .getSingleResult();

            assertEquals("new-name", newName);
            log.error("New name is " + newName);

            CriteriaBuilder cb = sessionFactory.getCurrentSession().getCriteriaBuilder();
            CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
            Root<Foo> root = cq.from(Foo.class);
            cq.where(cb.equal(root.get(Foo_.id), id));
            Query query = sessionFactory.getCurrentSession().createQuery(cq);

            Foo foo2 = (Foo) query.getSingleResult();
            log.error("New name is " + foo2.getName()); // Prints "old-name"
        });
    }

İşte kurulum kodum:

@ExtendWith(DropwizardExtensionsSupport.class)
public class UpdateTest {
    private SessionFactory sessionFactory;

    public DAOTestExtension database = DAOTestExtension.newBuilder()
        .addEntityClass(Foo.class)
        .build();

    @BeforeEach
    public void setup() {
        sessionFactory = database.getSessionFactory();
    }
...
}

FooSınıfı da gösterebilirim , ama çok da ilginç değil.

Yanıtlar

1 ChristianBeikov Aug 18 2020 at 09:16

FooÖrneğin L1 önbelleği yani güncelleme açıklamada alanına temas etmemelidir Geçerli oturum halen devam ediyor. Hazırda Bekletme / JPA, bir oturumun varlık nesneleri için kimliğini korumak zorunda olduğundan, güncelleme bildirimi nedeniyle oturumu temizleyemez. Genellikle, bir güncelleme ifadesinden sonra mevcut durumu tekrar yansıtmak için oturumu temizlemek veya örnekleri yenilemek gerekir.

sessionFactory.getCurrentSession().clear();Bunun yerine okuma işleminizin başında yapmayı deneyin