实体管理器如何读取其他人插入的新记录

时间:2014-06-06 02:20:40

标签: java hibernate jpa

我的应用程序使用JPA / hibernate从数据库中读取数据。应用程序是只读的,数据由其他程序插入。

问题是我的应用程序只能在第一次读取肉体数据。当其他程序插入新数据时,我的应用程序无法看到它。

这是我的测试代码:

public class TestJpaRead {
   private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.hibernate.tutorial.jpa");

   public static void main(String[] args) {
       LOG.debug("first time");
       countRow();   //output row size = X

       //set break point here, and manually insert an new row by using mysql client

       LOG.debug("second time");
       countRow();   //should output row size = X + 1, but it is still X
   }

   public static void countRow() {
       EntityManager em = emf.createEntityManager();
       Query query = em.createQuery("SELECT a FROM " + Report.class.getSimpleName() + " a");
       List result = query.getResultList();
       LOG.debug("countRow: {}", result.size());
       em.close();
   }
}

这是我的persistence.xml(没什么特别的):

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
         version="2.0">

<persistence-unit name="org.hibernate.tutorial.jpa" transaction-type="RESOURCE_LOCAL">
    <description>
        Persistence unit for the JPA tutorial of the Hibernate Getting Started Guide
    </description>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <properties>
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/foo" />
        <property name="javax.persistence.jdbc.user" value="root" />
        <property name="javax.persistence.jdbc.password" value="bar" />

        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.hbm2ddl.auto" value="auto" />
    </properties>

</persistence-unit>

谢谢!

1 个答案:

答案 0 :(得分:0)

从MySQL查询日志中,我找到了问题的原因:

                   48 Query SET autocommit=0
140606 11:35:41    48 Query select report0_.id from Report report0_  /*countRow()*/
                   48 Query SHOW WARNINGS
140606 11:35:42    48 Query select report0_.id from Report report0_  /*countRow()*/
                   48 Query SHOW WARNINGS
  1. 默认情况下,Hibernate在自动提交模式下不起作用。

  2. em.close()不隐式提交或回滚事务,即JDBC连接和事务仍处于活动/打开状态。 这是我误解的。 (emf.close()实际上会关闭连接。)

  3. 当您从emf.createEntityManager()获取EntityManager时,新的 EntityManager可以重用旧的JDBC连接。这意味着你可以 在先前关闭的EntityManager打开的事务中。

  4. 当您处于未提交/已打开的事务中时,使用默认值 MySQL隔离级别,你看不到别人做出的改变。

  5. 解决方案:显式打开并提交事务,或告诉Hibernate允许自动提交的JDBC连接。参考:Select using hibernate