【发布时间】:2015-01-09 00:16:35
【问题描述】:
我有一个奇怪的问题,即 JPQL 查询显示了一些不一致的行为。我编写了以下方法,我希望从中获取给定员工的所有活动的列表,这些活动与给定的 TimePeriod 对象重叠。
public List<Activity> getAllActivities(Employee employee,
TimePeriod timePeriod) throws DatasetException {
if (employee == null || timePeriod == null) {
throw new IllegalArgumentException();
}
try {
final Query query = em
.createQuery("SELECT DISTINCT a from Activity a INNER JOIN a.employeeTimePeriods e"
+ " INNER JOIN e.timePeriods t WHERE "
+ " e.employee = ?1"
+ " AND a.time.day = ?2"
+ " AND ?3 < t.endTime"
+ " AND ?4 > t.startTime"
+ " ORDER BY a.time.startTime");
query.setParameter(1, employee);
query.setParameter(2, timePeriod.getDay());
query.setParameter(3, timePeriod.getStartTime());
query.setParameter(4, timePeriod.getEndTime());
return query.getResultList();
} catch (Exception e) {
LOGGER.error(String.format(
"Exception while getting all activities of employee %s, "
+ "which overlap time period %s.", employee,
timePeriod), e);
throw new DatasetException(
String.format(
"Error while getting all activities of employee %s, "
+ "which overlap time period %s: "
+ e.getMessage(), employee, timePeriod));
}
}
此外,我创建了一些测试用例: 我有一名员工,他参加了两项活动:
- 每周一 10:00 到 10:45
- 每周一 10:45 到 11:30
我有一个 TimePeriod 对象,日期设置为星期一,开始时间设置为 10:00,结束时间设置为 12:00。
现在,我希望始终从我的方法中获取先前列出的两个活动,但存在问题。我有时(!)只得到第一个,在其他时候测试用例成功。我有更多这种方法的测试用例,从未失败(但我只是注意到上面的测试用例是唯一的,它必须选择两个活动)。
我也有相同的房间测试用例(除了 TimePeriod 对象的开始时间是 09:00 之外),它从未失败过。但由于查询存在差异 - 在房间查询中我能够使用 MEMBER OF - 我猜测连接可能存在问题。
为了完整起见,房间查询:
final Query query = em.createQuery("SELECT a FROM Activity a WHERE"
+ " ?1 MEMBER OF a.rooms AND a.time.day = ?2"
+ " AND ?3 < a.time.endTime AND ?4 > a.time.startTime"
+ " ORDER BY a.time.startTime");
query.setParameter(1, room);
query.setParameter(2, timePeriod.getDay());
query.setParameter(3, timePeriod.getStartTime());
query.setParameter(4, timePeriod.getEndTime());
有人对我的问题有什么建议吗?
【问题讨论】:
-
尝试打开日志以查看生成的查询和使用的参数:wiki.eclipse.org/EclipseLink/Examples/JPA/Logging 这将有助于确定失败案例与成功案例的不同之处。
-
谢谢。就是这么做的。两个查询中选择参数的顺序只有一点点不同,但这确实不应该对查询执行产生任何影响。
-
你能显示在工作案例和非工作案例中与生成的 SQL 相关的参数吗?
-
我现在也有另一个与活动和员工相关的查询的问题,我完全不知道为什么会发生这种情况。成功和失败情况下的查询看起来几乎一样,只是开头略有不同:成功:
SELECT DISTINCT t1.ID, t1.TYPE, t1.DAY, t1.DURATION, t1.ENDTIME, t1.STARTTIME, t1.MEETINGTYPE_ID, t1.PROJECTTYPE_ID, t1.LESSONTYPE_ID--- 失败:SELECT DISTINCT t1.ID, t1.TYPE, t1.DAY, t1.DURATION, t1.ENDTIME, t1.STARTTIME, t1.LESSONTYPE_ID, t1.PROJECTTYPE_ID, t1.MEETINGTYPE_ID
标签: java jpa eclipselink jpql