I would like to retrieve the Reservation which has no reference ReservationInstance in DB by JPQL query. ReservationInstance entity have Reservation entity. It is OneToOne unidirectional.
Reservation Table
ID NAME
0001 AAA
0002 BBB
0003 CCC
0004 DDD
ReservationInstance Table
ID SOME_COLUMN RESERVATION_ID
0001 somedata 0004
How can I retrieve the Reservation list (For AAA, BBB and CCC) which has no ReservationInstance reference?
My Entities
public class Reservation implements Serializable {
.....
private String id;
.....
private String name;
//getter and setter
}
public class ReservationInstance implements Serializable {
....
private String id;
....
private Date fromTime;
....
private Date toTime;
@OneToOne
@JoinColumn(name = "RESERVATION_ID", referencedColumnName = "ID")
private Reservation reservation;
}
Update Post
I used the query as below
SELECT r FROM Reservation r LEFT JOIN ReservationInstance ri WHERE ri.reservation IS NULL
I get the exception
[EL Severe]: 2012-12-18 16:37:02.817--ServerSession(1733641680)--Local Exception Stack:
Exception [EclipseLink-8023] (Eclipse Persistence Services - 2.1.2.v20101206-r8635): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Syntax error parsing the query [Reservation.findAbandonedReservation: SELECT r FROM Reservation r LEFT JOIN ReservationInstance ri WHERE ri.reservation.id IS
NULL].
Internal Exception: org.eclipse.persistence.internal.libraries.antlr.runtime.EarlyExitException
at org.eclipse.persistence.exceptions.JPQLException.syntaxError(JPQLException.java:352)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.handleRecognitionException(JPQLParser.java:350)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.addError(JPQLParser.java:242)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.reportError(JPQLParser.java:359)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.joinAssociationPathExpression(JPQLParser.java:11880)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.join(JPQLParser.java:11488)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.identificationVariableDeclaration(JPQLParser.java:11302)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.fromClause(JPQLParser.java:11164)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.selectStatement(JPQLParser.java:355)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.document(JPQLParser.java:275)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.parse(JPQLParser.java:130)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.buildParseTree(JPQLParser.java:91)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:207)
at org.eclipse.persistence.internal.jpa.JPAQuery.processJPQLQuery(JPAQuery.java:106)
at org.eclipse.persistence.internal.jpa.JPAQuery.prepare(JPAQuery.java:90)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:509)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:470)
at org.eclipse.persistence.internal.sessions.AbstractSession.processJPAQueries(AbstractSession.java:1815)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:409)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:666)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:615)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:389)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:164)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:221)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:209)
at org.ace.mrbs.ost.comp.reservation.persistence.ReservationDAO.deleteAbandonedReservation(ReservationDAO.java:110)
at org.ace.mrbs.ost.comp.reservation.persistence.ReservationDAO.main(ReservationDAO.java:130)
Caused by: org.eclipse.persistence.internal.libraries.antlr.runtime.EarlyExitException
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.joinAssociationPathExpression(JPQLParser.java:11868)
... 23 more
MY first choice would be to make the relation Bi-Directional.
Turns out LEFT JOIN with ON will only be supported in JPA 2.1 so I suggest something like this:
Not 100% sure this works, if not try using
r.id IS NOT INsome query the returns the ids.