以下行尝试使用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()都不会返回结果,即使:
奇怪的事似乎在这里发生了!我应该在哪里看下一个?交易,缓存?
更新: 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();
答案 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环境中)