Hibernate在同一事务中执行不同查询导致执行相同查询的结果。

huangapple 未分类评论45阅读模式
标题翻译

Hibernate executing different queries in same transaction result in same executed query

问题

我正在尝试将Spring与Hibernate结合使用,但似乎无法在同一事务中执行两个查询:

@Autowired
private SessionFactory sessionFactory;

@Transactional
public void registerUser(String username, String email, String password) {
    System.out.println("查询 1:");
    CriteriaBuilder criteriaBuilder1 = sessionFactory.getCurrentSession().getCriteriaBuilder();
    CriteriaQuery<UserRecord> query1 = criteriaBuilder1.createQuery(UserRecord.class);
    Root<UserRecord> root1 = query1.from(UserRecord.class);
    query1 = query1.select(root1).where(criteriaBuilder1.and(
            criteriaBuilder1.equal(root1.get("users_name"), "name"),
            criteriaBuilder1.equal(root1.get("users_email"), "email@test.com")));
    sessionFactory.getCurrentSession().createQuery(query1).uniqueResultOptional();

    System.out.println("查询 2:");
    CriteriaBuilder criteriaBuilder2 = sessionFactory.getCurrentSession().getCriteriaBuilder();
    CriteriaQuery<UserRecord> query2 = criteriaBuilder2.createQuery(UserRecord.class);
    Root<UserRecord> root2 = query2.from(UserRecord.class);
    query2 = query2.select(root2).where(criteriaBuilder2.equal(root2.get("users_email"), "email@test.com"));
    sessionFactory.getCurrentSession().createQuery(query2).uniqueResultOptional();
}

当我调用此代码时的结果如下(目前是在组件中调用的):

查询 1:
Hibernate:从users表中选择u1_0.users_pk、u1_0.users_email、u1_0.users_name,其中u1_0.users_name = ? 和 u1_0.users_email = ?
查询 2:
Hibernate:从users表中选择u1_0.users_pk、u1_0.users_email、u1_0.users_name,其中u1_0.users_name = ? 和 u1_0.users_email = ?

但我预期查询 2 应该是:

从users表中选择u1_0.users_pk、u1_0.users_email、u1_0.users_name,其中u1_0.users_email = ?

如果我交换查询 1 和查询 2,结果如下:

查询 1:
Hibernate:从users表中选择u1_0.users_pk、u1_0.users_email、u1_0.users_name,其中u1_0.users_email = ?
查询 2:
Hibernate:从users表中选择u1_0.users_pk、u1_0.users_email、u1_0.users_name,其中u1_0.users_email = ?

这是我的Hibernate配置的片段:

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan(DAO_PACKAGE);
    sessionFactory.setHibernateProperties(hibernateProperties());
    return sessionFactory;
}

private Properties hibernateProperties() {
    Properties hibernateProperties = new Properties();
    hibernateProperties.setProperty("hibernate.show_sql", "true");
    hibernateProperties.setProperty("hibernate.dialect", databaseProperties.getDatabaseType().getDialect());
    return hibernateProperties;
}

@Bean
public PlatformTransactionManager hibernateTransactionManager() {
    HibernateTransactionManager transactionManager = new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory().getObject());
    return transactionManager;
}

是否我配置Spring与Hibernate的方式不正确(或者我对查询API的使用不正确)?

我的依赖项信息:

  • org.springframework.spring-orm: 5.2.4.RELEASE
  • org.hibernate.orm.hibernate-core: 6.0.0.Alpha4
  • org.apache.tomcat.tomcat-dbcp: 10.0.0-M1
  • org.postgresql.postgresql: 42.2.10
英文翻译

I'm trying out the combination of spring with hibernate, but I don't seem to be able to execute 2 queries in the same transaction:

@Autowired
private SessionFactory sessionFactory;

@Transactional
public void registerUser(String username, String email, String password) {
    System.out.println(&quot;Query 1:&quot;);
    CriteriaBuilder criteriaBuilder1 = sessionFactory.getCurrentSession().getCriteriaBuilder();
    CriteriaQuery&lt;UserRecord&gt; query1 = criteriaBuilder1.createQuery(UserRecord.class);
    Root&lt;UserRecord&gt; root1 = query1.from(UserRecord.class);
    query1 = query1.select(root1).where(criteriaBuilder1.and(
            criteriaBuilder1.equal(root1.get(&quot;users_name&quot;), &quot;name&quot;),
            criteriaBuilder1.equal(root1.get(&quot;users_email&quot;), &quot;email@test.com&quot;)));
    sessionFactory.getCurrentSession().createQuery(query1).uniqueResultOptional();

    System.out.println(&quot;Query 2:&quot;);
    CriteriaBuilder criteriaBuilder2 = sessionFactory.getCurrentSession().getCriteriaBuilder();
    CriteriaQuery&lt;UserRecord&gt; query2 = criteriaBuilder2.createQuery(UserRecord.class);
    Root&lt;UserRecord&gt; root2 = query2.from(UserRecord.class);
    query2 = query2.select(root2).where(criteriaBuilder2.equal(root2.get(&quot;users_email&quot;), &quot;email@test.com&quot;));
    sessionFactory.getCurrentSession().createQuery(query2).uniqueResultOptional();
}

The result when I call this code is (it is called in a component for the moment):

Query 1:
Hibernate: select u1_0.users_pk, u1_0.users_email, u1_0.users_name from users as u1_0 where u1_0.users_name = ? and u1_0.users_email = ?
Query 2:
Hibernate: select u1_0.users_pk, u1_0.users_email, u1_0.users_name from users as u1_0 where u1_0.users_name = ? and u1_0.users_email = ?

But I expect query 2 to be:

select u1_0.users_pk, u1_0.users_email, u1_0.users_name from users as u1_0 where u1_0.users_email = ?

If I switch query 1 and query 2, the result is:

Query 1:
Hibernate: select u1_0.users_pk, u1_0.users_email, u1_0.users_name from users as u1_0 where u1_0.users_email = ?
Query 2:
Hibernate: select u1_0.users_pk, u1_0.users_email, u1_0.users_name from users as u1_0 where u1_0.users_email = ?

Here is a snippet from my hibernate config:

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan(DAO_PACKAGE);
    sessionFactory.setHibernateProperties(hibernateProperties());
    return sessionFactory;
}

private Properties hibernateProperties() {
    Properties hibernateProperties = new Properties();
    hibernateProperties.setProperty(&quot;hibernate.show_sql&quot;, &quot;true&quot;);
    hibernateProperties.setProperty(&quot;hibernate.dialect&quot;, databaseProperties.getDatabaseType().getDialect());
    return hibernateProperties;
}

@Bean
public PlatformTransactionManager hibernateTransactionManager() {
    HibernateTransactionManager transactionManager = new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory().getObject());
    return transactionManager;
}

Is the way I configured spring with hibernate not the correct way (or my usage of the query api not correct)?

Info, my dependencies:

  • org.springframework.spring-orm: 5.2.4.RELEASE
  • org.hibernate.orm.hibernate-core: 6.0.0.Alpha4
  • org.apache.tomcat.tomcat-dbcp: 10.0.0-M1
  • org.postgresql.postgresql: 42.2.10

huangapple
  • 本文由 发表于 2020年3月17日 02:26:40
  • 转载请务必保留本文链接:https://java.coder-hub.com/60711351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定