Named query in Entity Bean - Problem with embedded class
Hello Forum,
I'm trying to set up a named query in my Entity Bean and I'm unable to get
it up and running for an embedded class object.
The class hierarchy is as follows:
@MappedSuperclass
AbstractSapResultData (contains dayOfAggregation field)
^
|
@MappedSuperclass
AbstractSapUserData (contains the timeSlice field)
^
|
@Entity
SapUserData
The named query is as follows:
@NamedQuery(name = SapUserDataContext.NAMED_QUERY_NAME_COUNT_QUERY,
query ="SELECT COUNT(obj) FROM SapUserData AS obj WHERE "
+"obj.sapCustomerId"
+"= :"
+ SapResultDataContext.COLUMN_NAME_SAP_CUSTOMER_ID
+" AND "
+"obj.sapSystemId"
+"= :"
+ SapResultDataContext.COLUMN_NAME_SAP_SYSTEM_ID
+" AND "
+"obj.sapServerId"
+"= :"
+ SapResultDataContext.COLUMN_NAME_SAP_SERVER_ID
+" AND "
+"obj.dayOfAggregation.calendar"
+"= :"
+ DayContext.COLUMN_NAME_DAY_OF_AGGREGATION
+" AND "
+"obj.timeSlice.startTime"
+"= :"
+"timeSliceStartTime"
+" AND "
+"obj.timeSlice.endTime"
+"= :"
+"timeSliceEndTime")
The query deploys and runs except that part:
+"obj.dayOfAggregation.calendar"
+"= :"
+ DayContext.COLUMN_NAME_DAY_OF_AGGREGATION
I don't see any difference to the part of the query accessing the timeSlice
field which is also an embedded class object - I access it in exactly the same way:
+"obj.timeSlice.startTime"
+"= :"
+"timeSliceStartTime"
+" AND "
+"obj.timeSlice.endTime"
+"= :"
+"timeSliceEndTime"
The problem is that the complete query runs on JBoss application server
but on the SAP NetWeaver application server it only rund without the
+"obj.dayOfAggregation.calendar"
+"= :"
+ DayContext.COLUMN_NAME_DAY_OF_AGGREGATION
part - If I enable that part on SAP NetWeaver the server complains:
[EXCEPTION]
{0}#1#java.lang.IllegalArgumentException: line 1: Comparison'=' not definedfor dependent objects
SELECT COUNT(obj) FROM SapUserData AS obj WHERE obj.sapCustomerId= :sap_customer_id AND obj.sapSystemId= :sap_system_id AND obj.sapServerId= :sap_server_id AND obj.dayOfAggregation.calendar= :day_of_aggregation AND obj.timeSlice.startTime= :timeSliceStartTime AND obj.timeSlice.endTime= :timeSliceEndTime
^
I know that this isn't an application server specific forum but the SAP NetWeaver server is the most strict EJB 3.0 and JPA 1.0 implementation I've seen so far so I think I'm doing something wrong there.
Someone in the SAp forum mentioned:
The problem here is that you compare an input-parameter with an embeddable field of your entity.
Regarding to the JPQL-grammer (spec 4.14) you are not allowed to compare
with the non-terminal embeddable field but with the terminal fields of your
embeddable. Stating that your embedded class might have the fields
startTime and endTime your JPQL query might look like this:
Query q = em.createQuery("SELECT count(obj.databaseId) FROM SapUserData obj WHERE obj.timeSlice.startTime = :startTime AND obj.timeSlice.endTime = :endTime");
q.setParameter("startTime", foo.getStartTime());
q.setParameter("endTime", foo.getEndTime());
q.getResultList();
This limitation in the JPQL grammar is rather uncomfortable.
An automatic mapping of the parameter's fields to the terminal fields of your
embedded field would be more convenient. The same can be said for lists
as parameter-values which is possible in HQL, too. I think we have to wait
patiently for JPA 2.0 and hope for improvements there. :-)
With that help I was able to get it up and running for the timeSlice field but
I don't see the difference to the dayOfAggregation field which is also just
another embedded class using an object of a class annotated with
@Embeddable.
The get method of the dayOfAggregation field is as follows:
/**
* Get method for the member "<code>dayOfAggregation</code>".
*
* @return Returns the dayOfAggregation.
*/
@Embedded
@AttributeOverrides({@AttributeOverride(name ="calendar",/* Not possible to use interface constant here - field name must be used for reference */
column = @Column(name = DayContext.COLUMN_NAME_DAY_OF_AGGREGATION,
nullable =false)),
@AttributeOverride(name ="weekday",
column = @Column(name = DayContext.COLUMN_NAME_WEEKDAY,
nullable =false)),
})
public Day getDayOfAggregation(){
return this.dayOfAggregation;
}
The link to my question in the SAP forum for reference:
https://www.sdn.sap.com/irj/sdn/thread?messageID=3651350
Any help or ideas would be greatly appreciated.
Thanks in advance.
Henning Malzahn

