JPA EntityManager createQuery не возвращает результатов - PullRequest
2 голосов
/ 18 июля 2011

Следующая строка пытается извлечь все строки из таблицы базы данных «Sourcing» с помощью JPA2.0 EntityManager, управляемой контейнером JPA, однако не возвращает результатов, даже если в таблице 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 на консоль показывает оператор SQL с точки зрения Hibernate (отправляется в 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. Запуск "select * from Sourcing" изкомандная строка MySQL возвращает 2 результата
  2. копирование и вставка необработанного вывода SQL из Hibernate в командную строку MySQL также возвращает 2 результата
  3. журнал MySQL показывает, что строки были вставлены и зафиксированы в базе данных

Здесь происходит что-то странное!Где мне искать дальше?Транзакции, кеширование?

ОБНОВЛЕНИЕ: Класс Entity определен следующим образом (некоторые методы извлечения и удаления удалены):

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

ОБНОВЛЕНИЕ (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 ......

ОБНОВЛЕНИЕ 21 июля:

Я попытался выполнить запрос "select * from Sourcing", используя запрос JPA Criteria (ниже) вместо .createQuery ("из 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 Ответ

1 голос
/ 25 июля 2011

Решено: Строки в базе данных не становятся доступными для других транзакций (т. Е. EntityManager.merge ()) до тех пор, пока EJB-компонент не будет полностью выполнен, что позволяет транзакции COMMIT для базы данных. Используя ведение журнала MySQL, я заметил, что Hibernate выдал оператор «SET AUTOCOMMIT = 0», что приведет к выполнению операций вставки / обновления и т. Д. Оператором COMMIT, чтобы последующие запросы могли видеть эти строки. Таким образом, в конце моего EJB Message-Driven-Bean (возможно, это был Session bean) был цикл while, который не позволял bean-компоненту полностью выполняться и, следовательно, фиксировать его в базе данных. Мне не нужно было устанавливать какие-либо транзакционные значения для каждого метода внутри какого-либо компонента, и они могли бы быть счастливо вложены и использовать несколько EntityManager для одной и той же транзакции (в среде управляемых контейнером транзакций)

...