我使用的是EclipseLink和MySQL。我正在尝试从Room实体中检索一个值,而不是加入它。
以下是我在计划实体上的NamedQuery:
@NamedQuery(name = "Schedule.findUnusedRoomForCourseLectureOnly",
query = "SELECT r FROM Schedule s, Room r WHERE s.day = :sday AND (:stime NOT BETWEEN s.startTime AND s.endTime) AND r.id <> s.room.id")我从我的JPA控制器得到一个空值。
下面是控制程序的代码:
public Room findUnusedRoomForCourseLectureOnly(int day, Calendar startTime) {
EntityManager em = getEntityManager();
Query q = em.createNamedQuery("Schedule.findUnusedRoomForCourseLectureOnly")
.setParameter("sday", day)
.setParameter("stime", startTime);
q.setMaxResults(1);
try {
return (Room) q.getResultList().get(0);
} catch (IndexOutOfBoundsException e) {
return null;
} finally {
em.close();
}
}下面是我的计划实体:
@Entity
public class Schedule implements Serializable, Comparable<Schedule> {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "scheduledDay")
private int day;
@Temporal(javax.persistence.TemporalType.TIME)
private Calendar startTime; // 24 hr format
@Temporal(javax.persistence.TemporalType.TIME)
private Calendar endTime; // 24 hr format
@ManyToOne
private Faculty faculty;
@ManyToOne
private Room room;
@ManyToOne
private Subject subject;
private boolean lab;
@ManyToOne
private Section section;
public Schedule() {
this.startTime = Calendar.getInstance();
this.endTime = Calendar.getInstance();
}
public Schedule(int day, Calendar startTime, Calendar endTime, Faculty faculty, Room room, Subject subject, boolean lab, Section section) {
this.day = day;
this.startTime = startTime;
this.endTime = endTime;
this.faculty = faculty;
this.room = room;
this.subject = subject;
this.lab = lab;
this.section = section;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public Calendar getStartTime() {
return startTime;
}
public final void setStartTime(int hour) {
this.startTime.set(Calendar.HOUR_OF_DAY, hour);
this.startTime.set(Calendar.MINUTE, 0);
this.startTime.set(Calendar.SECOND, 0);
}
public Calendar getEndTime() {
return endTime;
}
public final void setEndTime(int hour) {
this.endTime.set(Calendar.HOUR_OF_DAY, hour);
this.endTime.set(Calendar.MINUTE, 0);
this.endTime.set(Calendar.SECOND, 0);
}
public Faculty getFaculty() {
return faculty;
}
public void setFaculty(Faculty faculty) {
this.faculty = faculty;
}
public Room getRoom() {
return room;
}
public void setRoom(Room room) {
this.room = room;
}
public Subject getSubject() {
return subject;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
public Section getSection() {
return section;
}
public void setSection(Section section) {
this.section = section;
}
public boolean isLab() {
return lab;
}
public void setLab(boolean lab) {
this.lab = lab;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Schedule)) {
return false;
}
Schedule other = (Schedule) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "ph.edu.bulsusc.planner.entity.Schedule[ id=" + id + " ]";
}
@Override
public int compareTo(Schedule schedule) {
// return
// -1 ahead
// 0 overlapping
// 1 behind
// int timeComparison = compareTime(schedule);
// boolean isTimeConflict = timeComparison == 0;
//
// if (this.room.getId() == schedule.getRoom().getId() && !isTimeConflict) {
// // if they have same room and time is not conflict
// return timeComparison;
// } else {
// // same room; time conflict
// return 0;
// }
throw new UnsupportedOperationException("Not implemented yet.");
}
// private int compareTime(Schedule schedule) {
// if (this.day.compareTo(schedule.getDay()) < 0) { // ahead/before of scheduled day
// return -1;
// } else if (this.day.compareTo(schedule.getDay()) == 0) { // overlapping day
// if (this.endTime.get(Calendar.HOUR_OF_DAY) < schedule.getStartTime().get(Calendar.HOUR_OF_DAY)) {
// return -1;
// } else if (this.startTime.get(Calendar.HOUR_OF_DAY) > schedule.getEndTime().get(Calendar.HOUR_OF_DAY)) {
// return 1;
// } else {
// return 0;
// }
// } else { // behind/after of scheduled day
// return 1;
// }
// }
}下面是我的Room实体:
@Entity
public class Room implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String number;
private boolean lab;
@OneToMany
private List<Course> prioritizedCourses;
@OneToMany
private List<Subject> prioritizedSubjects;
public Room() {
}
public Room(String number, boolean lab) {
this.number = number;
this.lab = lab;
}
public Room(String number, boolean lab, List<Course> prioritizedCourses, List<Subject> prioritizedSubjects) {
this.number = number;
this.lab = lab;
this.prioritizedCourses = prioritizedCourses;
this.prioritizedSubjects = prioritizedSubjects;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isLab() {
return lab;
}
public void setLab(boolean lab) {
this.lab = lab;
}
public List<Course> getPrioritizedCourses() {
return prioritizedCourses;
}
public void setPrioritizedCourses(List<Course> prioritizedCourses) {
this.prioritizedCourses = prioritizedCourses;
}
public List<Subject> getPrioritizedSubjects() {
return prioritizedSubjects;
}
public void setPrioritizedSubjects(List<Subject> prioritizedSubjects) {
this.prioritizedSubjects = prioritizedSubjects;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
// public List<Schedule> getSchedules() {
// return schedules;
// }
//
// /**
// * Rewrites schedule with this method
// * @param schedules
// */
// public void setSchedules(List<Schedule> schedules) {
// this.schedules = schedules;
// }
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Room)) {
return false;
}
Room other = (Room) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "ph.edu.bulsusc.planner.entity.Room[ id=" + id + " ]";
}
}我做错了吗?
发布于 2014-01-29 22:15:15
"r.id <> s.room.id“子句的问题是,使用"s.room.id”会导致时间表和房间之间的内部联接。您可能会尝试使用"r <> s.room“来避免连接,但我认为它不会对您想要的东西有所帮助。该查询将在同一查询中取消Room和Schedule的连接,从而导致笛卡尔连接-返回调度中的N行乘以调度中的M行,然后过滤出与r.id <> s.room.id子句匹配的几行。因此,如果您有多个时间表,所有房间都将被退还。
您可能希望在子查询的顶部使用not exist。类似于:
"SELECT r FROM Room r WHERE not exists (SELECT s from Schedule s where :stime NOT BETWEEN s.startTime AND s.endTime) AND r = s.room))"发布于 2014-01-29 21:34:14
"SELECT r FROM Room r WHERE r.id NOT IN (SELECT s.room.id FROM Schedule s WHERE s.day = :sday AND (:stime BETWEEN s.startTime AND s.endTime))"https://stackoverflow.com/questions/21428357
复制相似问题