JPA EntityManager createQuery不返回任何结果

时间:2011-07-18 07:52:12

标签: hibernate java-ee jpa jpa-2.0 entitymanager

以下行尝试使用JPA Container-Managed JPA2.0 EntityManager从数据库表“Sourcing”中检索所有行,但是它不返回任何结果,即使表中似乎有2行:

em.createQuery("from Sourcing").getResultList();

我正在使用JBoss 6.0,JVM 1.6,MySQL 5.5.10和Hibernate 3.6.3

最初持久化Sourcing对象的类是(汇总):

@Stateless
@Local
public final class MyBean implements MyBeanLocal {

    @PersistenceContext
    private EntityManager em;

    public MyBean() {}

    public void methodA() {
        methodB();
    }

    private void methodB() {
        methodC();
    }

    private void methodC() {
        Sourcing sourcing = new Sourcing( … values ...);
        em.persist(sourcing);
    }
}

控制台上的hibernate.show_sql输出从Hibernate的角度显示SQL语句(发送到MySQL)

select sourcing0_.sourcingId as sourcingId7_, sourcing0_.foundResults as foundRes2_7_, sourcing0_.numberOfAdults as numberOf3_7_, sourcing0_.numberofchildren as numberof4_7_, sourcing0_.numberofinfants as numberof5_7_, sourcing0_.numberofseniors as numberof6_7_, sourcing0_.scopeBeginDateTime as scopeBeg7_7_, sourcing0_.scopeEndDateTime as scopeEnd8_7_, sourcing0_.searchId as searchId7_, sourcing0_.searchDateTime as searchDa9_7_, sourcing0_.serviceId as serviceId7_, sourcing0_.sourceId as sourceId7_, sourcing0_.sourcingFinishDateTime as sourcin10_7_, sourcing0_.sourcingStartedDateTime as sourcin11_7_, sourcing0_.timeStamp as timeStamp7_, sourcing0_.version as version7_ from sourcing sourcing0_

MySQL日志文件的以下输出显示以前插入和提交的行:

223 Query   insert into sourcing (foundResults, numberOfAdults, numberofchildren, numberofinfants, numberofseniors, scopeBeginDateTime, scopeEndDateTime, searchId, searchDateTime, serviceId, sourceId, sourcingFinishDateTime, sourcingStartedDateTime, timeStamp, version) values (0, 1, 0, 0, 0, null, null, 1, '2011-08-15 00:00:00', 372, 2, null, '2011-07-18 15:47:00', null, 0)
223 Query   insert into sourcing (foundResults, numberOfAdults, numberofchildren, numberofinfants, numberofseniors, scopeBeginDateTime, scopeEndDateTime, searchId, searchDateTime, serviceId, sourceId, sourcingFinishDateTime, sourcingStartedDateTime, timeStamp, version) values (0, 1, 0, 0, 0, null, null, 1, '2011-08-15 00:00:00', 530, 2, null, '2011-07-18 15:47:00', null, 0)
224 Connect user@localhost on mydatabase
224 Query   /* mysql-connector-java-5.1.15 ( Revision: ${bzr.revision-id} ) */SHOW VARIABLES WHERE Variable_name ='language' OR Variable_name = 'net_write_timeout' OR Variable_name = 'interactive_timeout' OR Variable_name = 'wait_timeout' OR Variable_name = 'character_set_client' OR Variable_name = 'character_set_connection' OR Variable_name = 'character_set' OR Variable_name = 'character_set_server' OR Variable_name = 'tx_isolation' OR Variable_name = 'transaction_isolation' OR Variable_name = 'character_set_results' OR Variable_name = 'timezone' OR Variable_name = 'time_zone' OR Variable_name = 'system_time_zone' OR Variable_name = 'lower_case_table_names' OR Variable_name = 'max_allowed_packet' OR Variable_name = 'net_buffer_length' OR Variable_name = 'sql_mode' OR Variable_name = 'query_cache_type' OR Variable_name = 'query_cache_size' OR Variable_name = 'init_connect'
224 Query   /* mysql-connector-java-5.1.15 ( Revision: ${bzr.revision-id} ) */SELECT @@session.auto_increment_increment
224 Query   SHOW COLLATION
224 Query   SET NAMES latin1
224 Query   SET character_set_results = NULL
224 Query   SET autocommit=1
224 Query   SET sql_mode='STRICT_TRANS_TABLES'
224 Query   SELECT @@session.tx_isolation
224 Query   SET autocommit=0
.....
223 Query   commit
224 Query   select sourcing0_.sourcingId as sourcingId7_, sourcing0_.foundResults as foundRes2_7_, sourcing0_.numberOfAdults as numberOf3_7_, sourcing0_.numberofchildren as numberof4_7_, sourcing0_.numberofinfants as numberof5_7_, sourcing0_.numberofseniors as numberof6_7_, sourcing0_.scopeBeginDateTime as scopeBeg7_7_, sourcing0_.scopeEndDateTime as scopeEnd8_7_, sourcing0_.searchId as searchId7_, sourcing0_.searchDateTime as searchDa9_7_, sourcing0_.serviceId as serviceId7_, sourcing0_.sourceId as sourceId7_, sourcing0_.sourcingFinishDateTime as sourcin10_7_, sourcing0_.sourcingStartedDateTime as sourcin11_7_, sourcing0_.timeStamp as timeStamp7_, sourcing0_.version as version7_ from sourcing sourcing0_

总之,任何想法为什么createQuery(“来自Sourcing”)。getResultList()都不会返回结果,即使:

  1. 从MySQL命令行运行“select * from Sourcing”返回2结果
  2. 将原始SQL输出从Hibernate复制并粘贴到MySQL命令行中也会返回2个结果
  3. MySQL日志显示已插入行并将其提交到数据库
  4. 奇怪的事似乎在这里发生了!我应该在哪里看下一个?交易,缓存?

    更新: Entity类定义如下(删除了一些getter和setter):

    @Entity
    @Table(name = "sourcing")
    public class Sourcing implements java.io.Serializable, Cloneable {
    
    private static final long serialVersionUID = 1L;
    private Integer sourcingId;
    private Service service;
    private Search search;
    private Source source;
    private Date searchDateTime;
    private Date sourcingStartedDateTime;
    private Date sourcingFinishedDateTime;
    private Date scopeBeginDateTime;
    private Date scopeEndDateTime;
    private Integer numberOfAdults;
    private Integer numberOfChildren;
    private Integer numberOfInfants;
    private Integer numberOfSeniors;
    private Boolean foundResults;
    
    private int version;
    private Date timeStamp;
    
    private boolean isFareMonitoring = false;
    
    private List<Flight> flights = new ArrayList<Flight>(0);
    private List<Segment> segments = new ArrayList<Segment>(0);
    private List<Fare> fares = new ArrayList<Fare>(0);
    
    public Sourcing() {
    }
    
    public Sourcing(Search search, Source source, Service service,
            Date sourcingStartedDateTime,
            Integer numberOfAdults, Integer numberOfChildren,
            Integer numberOfInfants, Integer numberOfSeniors,
            Boolean foundResults) {
    
        this.search = search;
        this.source = source;
        this.service = service;
        this.sourcingStartedDateTime = sourcingStartedDateTime;
        this.numberOfAdults = numberOfAdults;
        this.numberOfChildren = numberOfChildren;
        this.numberOfInfants = numberOfInfants;
        this.numberOfSeniors = numberOfSeniors;
        this.foundResults = foundResults;
    
        if (search.isFareMonitoring()) {
            this.isFareMonitoring = true;
        }
    }
    
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "sourcingId", unique = true, nullable = false)
    public Integer getSourcingId() {
        return this.sourcingId;
    }
    
    public void setSourcingId(Integer sourcingId) {
        this.sourcingId = sourcingId;
    }
    
    @Version
    @Column(columnDefinition="TINYINT")
    public int getVersion() {
        return version;
    }
    
    public void setVersion(int version) {
        this.version = version;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="timeStamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
    public Date getTimeStamp() {
        return timeStamp;
    }
    
    public void setTimeStamp(Date timeStamp) {
        this.timeStamp = timeStamp;
    }
    
     // to make 3 days, beginOffSet = -1, endOffSet = 1 [ i.e. -1, 0, 1]
    public static void setScope(Sourcing sourcing, int beginOffSet, int endOffSet) {  
    
        Calendar cal = new GregorianCalendar();
        cal.setTime(sourcing.getSearchDateTime());
    
        cal.add(Calendar.DAY_OF_MONTH, beginOffSet);
        sourcing.setScopeBeginDateTime(cal.getTime());
    
        cal.add(Calendar.DAY_OF_MONTH, (-beginOffSet + endOffSet)); // --1 + 1 = 2
        sourcing.setScopeEndDateTime(cal.getTime());
    }
    
    @Transient
    public final boolean isFareMonitoring() {
        return isFareMonitoring;
    }
    
    public final void setFareMonitoring(boolean isFareMonitoring) {
        this.isFareMonitoring = isFareMonitoring;
    }
    }
    

    UPDATE(7月20日)我按照建议启用了org.hibernate.jdbc和org.hibernate.loader TRACE日志记录。输出如下:

    18:25:02,891 DEBUG [com.myproject.beans.ReceiveFareBean] SLEEPING FOR 3 SECONDS ......
    18:25:05,890 DEBUG [com.myproject.beans.ReceiveFareBean] AWAKE. 
    18:25:05,891 TRACE [org.hibernate.engine.query.QueryPlanCache] located HQL query plan in cache (from Sourcing)
    18:25:05,891 TRACE [org.hibernate.engine.query.QueryPlanCache] located HQL query plan in cache (from Sourcing)
    18:25:05,891 TRACE [org.hibernate.engine.query.HQLQueryPlan] find: from Sourcing
    18:25:05,891 TRACE [org.hibernate.engine.QueryParameters] named parameters: {}
    18:25:05,891 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    18:25:05,891 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
    18:25:05,891 DEBUG [org.hibernate.SQL] select sourcing0_.sourcingId as sourcingId7_, sourcing0_.foundResults as foundRes2_7_, sourcing0_.numberOfAdults as numberOf3_7_, sourcing0_.numberofchildren as numberof4_7_, sourcing0_.numberofinfants as numberof5_7_, sourcing0_.numberofseniors as numberof6_7_, sourcing0_.scopeBeginDateTime as scopeBeg7_7_, sourcing0_.scopeEndDateTime as scopeEnd8_7_, sourcing0_.searchId as searchId7_, sourcing0_.searchDateTime as searchDa9_7_, sourcing0_.serviceId as serviceId7_, sourcing0_.sourceId as sourceId7_, sourcing0_.sourcingFinishDateTime as sourcin10_7_, sourcing0_.sourcingStartedDateTime as sourcin11_7_, sourcing0_.timeStamp as timeStamp7_, sourcing0_.version as version7_ from sourcing sourcing0_
    18:25:05,892 INFO  [STDOUT] Hibernate: select sourcing0_.sourcingId as sourcingId7_, sourcing0_.foundResults as foundRes2_7_, sourcing0_.numberOfAdults as numberOf3_7_, sourcing0_.numberofchildren as numberof4_7_, sourcing0_.numberofinfants as numberof5_7_, sourcing0_.numberofseniors as numberof6_7_, sourcing0_.scopeBeginDateTime as scopeBeg7_7_, sourcing0_.scopeEndDateTime as scopeEnd8_7_, sourcing0_.searchId as searchId7_, sourcing0_.searchDateTime as searchDa9_7_, sourcing0_.serviceId as serviceId7_, sourcing0_.sourceId as sourceId7_, sourcing0_.sourcingFinishDateTime as sourcin10_7_, sourcing0_.sourcingStartedDateTime as sourcin11_7_, sourcing0_.timeStamp as timeStamp7_, sourcing0_.version as version7_ from sourcing sourcing0_
    18:25:05,892 TRACE [org.hibernate.jdbc.AbstractBatcher] preparing statement
    18:25:05,892 TRACE [org.hibernate.loader.Loader] Bound [1] parameters total
    18:25:05,892 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open ResultSet (open ResultSets: 0, globally: 0)
    18:25:05,893 TRACE [org.hibernate.loader.Loader] processing result set
    18:25:05,893 TRACE [org.hibernate.loader.Loader] done processing result set (0 rows)
    18:25:05,893 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close ResultSet (open ResultSets: 1, globally: 1)
    18:25:05,893 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    18:25:05,893 TRACE [org.hibernate.jdbc.AbstractBatcher] closing statement
    18:25:05,893 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
    18:25:05,893 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
    18:25:05,893 TRACE [org.hibernate.loader.Loader] total objects hydrated: 0
    18:25:05,893 DEBUG [org.hibernate.engine.StatefulPersistenceContext] initializing non-lazy collections
    18:25:05,893 DEBUG [com.myproject.beans.ReceiveFareBean] NUMBER OF SOURCINGS CURRENTLY IN THE DATABASE = 0
    18:25:05,893 DEBUG [com.myproject.beans.ReceiveFareBean] SLEEPING FOR 3 SECONDS ......
    

    7月21日更新:

    我使用JPA Criteria查询(下面)而不是.createQuery(“来自Sourcing”)尝试“select * from Sourcing”查询以查看它是否有所作为,但它没有解决问题(仍然没有结果返回)

    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Sourcing> criteriaQuery = criteriaBuilder.createQuery(Sourcing.class);
    Root<Sourcing> sourcing = criteriaQuery.from(Sourcing.class);
    criteriaQuery.select(sourcing);
    TypedQuery<Sourcing> typedQuery = em.createQuery(criteriaQuery);
    List<Sourcing> sourcings = typedQuery.getResultList();
    

1 个答案:

答案 0 :(得分:1)

解决: 在EJB bean完全执行之前,数据库中的行不可用于其他事务(即EntityManager.merge()),因此允许事务COMMIT到数据库。通过使用MySQL日志记录,我注意到Hibernate发出了语句“SET AUTOCOMMIT = 0”,这将导致插入/更新等由COMMIT语句继续,以便后续查询查看这些行。 因此,在我的EJB Message-Driven-Bean(可能是一个Session bean)的末尾有一个while循环,它阻止bean完全执行,因此提交到数据库。我不需要在任何bean中设置任何per-methods Transactional值,并且可以愉快地嵌套它们,并为同一事务使用多个EntityManagers(在Container Managed Transaction环境中)