2010-12-20 7 views
0

Ich habe Probleme mit einer JPA-Abfrage auf die Verwendung Umwandlung der Kriterien APIJPA 2 Kriterien API - Ausnahme JPQL zu Criteria API-Abfrage mit Eclipse Umwandlung

Ich habe die folgende Abfrage, die eine ServiceUser passende eine bestandene zu finden versucht, Adressparameter. ServiceUser ist eine abstrakte Entität mit den konkreten Unterklassen Child und Adult. Ich verwende die verknüpfte Vererbungsstrategie für die ServiceUser-Klasse.

Alles funktioniert gut, wenn ich diese Methode aufrufen.

public Set<T> findByAddress(Address address) { 

    Query query = manager.createQuery("SELECT distinct s FROM ServiceUser AS s JOIN s.addressHistory as h where h = :address"); 
    query.setParameter("address", address); 

    HashSet<T> result = new HashSet<T>(); 
    for (Object s : query.getResultList()) { 
     // tClass is the runtime type of the generic session bean. 
     if (this.tClass.isInstance(s)) { 
      result.add((T) s); 
     } 
    } 

    return result; 
} 

Aber, wenn ich versuche, die Funktion mit dem folgenden zu ersetzen, die die erzeugte Metamodell und typedquery verwendet dann ich

public Set<T> findByAddress(Address address) { 

    CriteriaBuilder cb = manager.getCriteriaBuilder(); 
    CriteriaQuery<ServiceUser> cq = cb.createQuery(ServiceUser.class); 
    Root<ServiceUser> su = cq.from(ServiceUser.class); 

    Join<ServiceUser, Address> addressHistory = su.join(ServiceUser_.addressHistory); 
    cq.select(su).distinct(true).where(cb.equal(addressHistory, cb.parameter(Address.class, "address"))); 
    TypedQuery<ServiceUser> q = manager.createQuery(cq); 
    q.setParameter("address", address); 

    HashSet<T> result = new HashSet<T>(); 
    for (ServiceUser s : q.getResultList()) { 
     // tClass is the runtime type of the generic session bean. 
     if (this.tClass.isInstance(s)) { 
      result.add((T) s); 
     } 
    } 

    return result; 
} 

hier eine Ausnahme bin immer ist die Stacktrace Protokollierung Eclipslink wird. Es scheint eine NulPointerException geworfen zu werden, aber ich bin mir nicht sicher warum?

/** 
Test : shouldBeAbleToFindChildByAddress() 
uk.gov.sunderland.ccms.model.bean.ChildService.findByAddress(Address[id=1,lineOne=7,lineTwo=Camberwell Way,lineThree=Moorside,lineFour=Sunderland,postcode=SR7 3XN]) 
[EL Finer]: 2010-12-20 12:39:42.89--ServerSession(7055953)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--client acquired 
[EL Finer]: 2010-12-20 12:39:42.89--UnitOfWork(22763294)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--TX binding to tx mgr, status=STATUS_ACTIVE 
[EL Finest]: 2010-12-20 12:39:42.89--UnitOfWork(22763294)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--Execute query ReadObjectQuery(referenceClass=Address sql="SELECT ID, LINE_TWO, LINE_THREE, LINE_ONE, LINE_FOUR, POSTCODE FROM ADDRESS WHERE (ID = ?)") 
[EL Finest]: 2010-12-20 12:39:42.906--UnitOfWork(22763294)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--Execute query ReadAllQuery(referenceClass=ServiceUser) 
[EL Finest]: 2010-12-20 12:39:42.906--ServerSession(7055953)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--reconnecting to external connection pool 
[EL Fine]: 2010-12-20 12:39:42.906--ServerSession(7055953)--Connection(32184426)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--SELECT DISTINCT t2.SERVICE_USER_TYPE FROM ADDRESS t0, SERVICE_USER t2, SERVICE_USER_ADDRESS t1 WHERE ((? = t0.ID) AND ((t1.SERVICE_USER_ID = t2.ID) AND (t0.ID = t1.ADDRESS_ID))) 
     bind => [1] 
[EL Finer]: 2010-12-20 12:39:42.906--UnitOfWork(22763294)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--class uk.gov.sunderland.ccms.model.entity.Adult 
[EL Finest]: 2010-12-20 12:39:42.906--ServerSession(7055953)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--reconnecting to external connection pool 
[EL Fine]: 2010-12-20 12:39:42.906--ServerSession(7055953)--Connection(29495316)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--SELECT DISTINCT t0.ID, t0.SERVICE_USER_TYPE, t0.TITLE, t0.DOB, t0.GENDER, t0.DISABILITY, t0.ETHNICITY, t1.ID, t1.EMPLOYMENT, t1.INFO_PACK_REQUIRED, t1.HOME_PHONE, t1.OTHER_LANGUAGE, t1.REFERRER, t1.MOBILE_PHONE, t1.LONE_PARENT, t1.GP_PRACTICE, t1.CONTACTABLE, t1.WORK_PHONE, t1.BABY_DUE_DATE, t1.ENGLISH_LEVEL FROM SERVICE_USER_ADDRESS t3, ADDRESS t2, ADULT t1, SERVICE_USER t0 WHERE (((? = t2.ID) AND ((t1.ID = t0.ID) AND (t0.SERVICE_USER_TYPE = ?))) AND ((t3.SERVICE_USER_ID = t0.ID) AND (t2.ID = t3.ADDRESS_ID))) 
     bind => [1, 1] 
[EL Warning]: 2010-12-20 12:39:42.906--UnitOfWork(22763294)--Thread(Thread[pool-52-thread-1,5,grizzly-kernel])--java.lang.NullPointerException 
     at org.eclipse.persistence.descriptors.InheritancePolicy.selectAllRowUsingDefaultMultipleTableSubclassRead(InheritancePolicy.java:1355) 
     at org.eclipse.persistence.descriptors.InheritancePolicy.selectAllRowUsingMultipleTableSubclassRead(InheritancePolicy.java:1396) 
     at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2493) 
     at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:407) 
     at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1074) 
     at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:736) 
     at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1034) 
     at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:380) 
     at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1112) 
     at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2909) 
     at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1291) 
     at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1273) 
     at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1247) 
     at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:479) 
     at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:714) 
*/ 

an dem SQL-Suche, die mit der fehlerhaften Kriterien api Abfrage und den Vergleich mit dem SQL ausgegeben werden, die ausgegeben wird, wenn ich die Abfrage mit der JPA String-Abfrage durchführen.

Criteria Abfrage

SELECT DISTINCT t0.ID, t0.SERVICE_USER_TYPE, t0.TITLE, t0.DOB, t0.GENDER, t0.DISABILITY, t0.ETHNICITY, t1.ID, t1.EMPLOYMENT, t1.INFO_PACK_REQUIRED, t1.HOME_PHONE, t1.OTHER_LANGUAGE, t1.REFERRER, t1.MOBILE_PHONE, t1.LONE_PARENT, t1.GP_PRACTICE, t1.CONTACTABLE, t1.WORK_PHONE, t1.BABY_DUE_DATE, t1.ENGLISH_LEVEL 
FROM SERVICE_USER_ADDRESS t3, ADDRESS t2, ADULT t1, SERVICE_USER t0 
WHERE (((? = t2.ID) AND ((t1.ID = t0.ID) AND (t0.SERVICE_USER_TYPE = ?))) 
AND ((t3.SERVICE_USER_ID = t0.ID) AND (t2.ID = t3.ADDRESS_ID))) 

JPA String-Abfrage

SELECT DISTINCT t0.ID, t0.SERVICE_USER_TYPE, t0.TITLE, t0.DOB, t0.GENDER, t0.DISABILITY, t0.ETHNICITY, t1.ID, t1.EMPLOYMENT, t1.INFO_PACK_REQUIRED, t1.HOME_PHONE, t1.OTHER_LANGUAGE, t1.REFERRER, t1.MOBILE_PHONE, t1.LONE_PARENT, t1.GP_PRACTICE, t1.CONTACTABLE, t1.WORK_PHONE, t1.BABY_DUE_DATE, t1.ENGLISH_LEVEL 
FROM SERVICE_USER_ADDRESS t3, ADDRESS t2, ADULT t1, SERVICE_USER t0 
WHERE (((? = t2.ID) AND ((t1.ID = t0.ID) AND (t0.SERVICE_USER_TYPE = ?))) 
AND ((t3.SERVICE_USER_ID = t0.ID) AND (t2.ID = t3.ADDRESS_ID))) 

und

SELECT DISTINCT t0.ID, t0.SERVICE_USER_TYPE, t0.TITLE, t0.DOB, t0.GENDER, t0.DISABILITY, t0.ETHNICITY, t1.ID 
FROM SERVICE_USER_ADDRESS t3, ADDRESS t2, CHILD t1, SERVICE_USER t0 WHERE (((? = t2.ID) AND ((t1.ID = t0.ID) AND (t0.SERVICE_USER_TYPE = ?))) AND ((t3.SERVICE_USER_ID = t0.ID) AND (t2.ID = t3.ADDRESS_ID))) 

Ich kann sehen, dass der erste Teil, der mit der Erwachsenenunterklasse von ServiceUser beschäftigt ist in beiden Fällen identisch, aber wenn es um die Kinderunterklasse die Kriterien Abfrage

[EL Warning]: 2010-12-20)--java.lang.NullPointerException 
     at org.eclipse.persistence.descriptors.InheritancePolicy.selectAllRowUsingDefaultMultipleTableSubclassRead(InheritancePolicy.java:1355) 

Könnte dies ein Fehler sein, mit Eclipse wirft

kommt?

Antwort

0

Ja, das scheint in der Tat ein Problem mit Eclipselink zu sein

<dependency> 
    <groupId>org.eclipse.persistence</groupId> 
    <artifactId>eclipselink</artifactId> 
    <version>2.1.1</version> 
    <scope>provided</scope> 
</dependency> 

Ändern der Vererbungsstrategie von

@Inheritance(strategy = InheritanceType.JOINED) 

zu

@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 

auf der abstrakten Basisklasse SERVICE_USER bietet eine Abhilfe das ist in meinem Fall in Ordnung.