내 JQL 쿼리가 동등한 CriteriaBuilder 쿼리와 다른 결과를 반환하는 이유는 무엇입니까?
Dropwizard Hibernate를 사용하고 있으며 테스트에 문제가 있습니다. 이 예제를 최대한 단순화했습니다. 을 만들고 Foo
업데이트 한 다음 가져 오려고합니다. 원시 쿼리를 사용하면 올바른 결과를 얻지 만 동등한 CriteriaBuilder 쿼리는 업데이트를 포착하지 못합니다. 내가 도대체 뭘 잘못하고있는 겁니까?
@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
Foo
인스턴스는 L1 캐시, 즉 업데이트 문에 감동하지 않는 현재 세션에서 아직도있다. Hibernate / JPA는 세션의 엔티티 객체에 대한 ID를 유지해야하므로 update 문으로 인해 세션을 지울 수 없습니다. 일반적으로 현재 상태를 다시 반영하려면 update 문 후에 세션을 지우거나 인스턴스를 새로 고쳐야합니다.
sessionFactory.getCurrentSession().clear();
읽기 트랜잭션을 시작할 때 대신 시도하십시오.