मेरी JQL क्वेरी समतुल्य मानदंड बाइब्रल क्वेरी से भिन्न परिणाम क्यों लौटाती है?

Aug 17 2020

मैं ड्रापवॉइडर हाइबरनेट का उपयोग कर रहा हूं और मेरे परीक्षणों के साथ समस्या है। मैंने इस उदाहरण को यथासंभव सरल बनाया है। मैं एक बनाता हूं Foo, इसे अपडेट करता हूं , और फिर इसे लाने की कोशिश करता हूं । कच्ची क्वेरी का उपयोग करने से सही परिणाम प्राप्त होता है, लेकिन समतुल्य क्राइटेरियाबाउट क्वेरी अपडेट को पकड़ नहीं पाती है। मैं क्या गलत कर रहा हूं?

    @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"
        });
    }

यहाँ मेरा सेटअप कोड है:

@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();
    }
...
}

मैं Fooकक्षा भी दिखा सकता हूं , लेकिन यह बहुत दिलचस्प नहीं है।

जवाब

1 ChristianBeikov Aug 18 2020 at 09:16

Fooउदाहरण के एल 1 कैश यानी वर्तमान सत्र जो अद्यतन बयान से छुआ नहीं है में अब भी है। चूंकि Hibernate / JPA को किसी सत्र की इकाई वस्तुओं के लिए पहचान बनाए रखना है, इसलिए यह अपडेट स्टेटमेंट के कारण सत्र को खाली नहीं कर सकता है। आमतौर पर, किसी व्यक्ति को वर्तमान स्थिति को फिर से प्रतिबिंबित करने के लिए अपडेट स्टेटमेंट के बाद सत्र या रिफ्रेश इंस्टेंस को खाली करना पड़ता है।

sessionFactory.getCurrentSession().clear();इसके बजाय अपने पढ़े गए लेन-देन की शुरुआत में प्रयास करें