JPQL LEFT JOIN FETCH Results in NPE when DescriptorCustomizer in Place

I have a unidirectional one-to-many mapping between the following two entities:
@Entity
@Table(name="INVC_CNTRL")
public class InvoiceControl implements Serializable {
    @Id
    @Column(name="INVC_CNTRL_ID")
    private Long invoiceControlId = null;
    @OneToMany(fetch = FetchType.LAZY)
    private List userDefineds;
@Entity
@Table(name="USER_DEFINED")
public class UserDefined implements Serializable {
    @Column(name="USER_DEFINED_TABLE")
    private java.lang.String userDefinedTable;
    @Column(name="USER_DEFINED_FK")
    private long userDefinedForeignKey;
I wrote the following DescriptorCustomizer to address a constant JoinColumn value:
        ManyToManyMapping mapping = (ManyToManyMapping) descriptor.getMappingForAttributeName("userDefineds");
        if (null != mapping) {
            String tableName = descriptor.getTableName();
            String primaryKey = descriptor.getPrimaryKeyFields().get(0).getName();
            ExpressionBuilder builder = new ExpressionBuilder(mapping.getReferenceClass());
            mapping.setSelectionCriteria(builder.getField("USER_DEFINED_FK").equal(builder.getParameter(primaryKey))
                .and(builder.getField("USER_DEFINED_TABLE").equal(tableName)));
This works as expected with JPQL "select a from InvoiceControl a join fetch a.userDefineds" but when I change the "join fetch" to "left join fetch", I get the following NPE:
Caused by: java.lang.NullPointerException
     at org.eclipse.persistence.internal.expressions.SQLSelectStatement.appendFromClauseForOuterJoin(SQLSelectStatement.java:403)
     at org.eclipse.persistence.internal.expressions.SQLSelectStatement.appendFromClauseToWriter(SQLSelectStatement.java:521)
     at org.eclipse.persistence.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1679)
     at org.eclipse.persistence.internal.databaseaccess.DatabasePlatform.printSQLSelectStatement(DatabasePlatform.java:3178)
     at org.eclipse.persistence.platform.database.OraclePlatform.printSQLSelectStatement(OraclePlatform.java:932)
     at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:782)
     at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:792)
     at org.eclipse.persistence.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:813)
     at org.eclipse.persistence.internal.queries.StatementQueryMechanism.setCallFromStatement(StatementQueryMechanism.java:390)
     at org.eclipse.persistence.internal.queries.StatementQueryMechanism.prepareSelectAllRows(StatementQueryMechanism.java:315)
     at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareSelectAllRows(ExpressionQueryMechanism.java:1721)
     at org.eclipse.persistence.queries.ReadAllQuery.prepareSelectAllRows(ReadAllQuery.java:813)
     at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:744)
     at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:661)
     ... 8 more
Inspecting the 2.5.1 source, this suggests relationAlias is null.
I've tried a number of things to no avail. If I disable the DescriptorCustomizor and instead add a @JoinColumn on the OneToMany defining half of the join, it works. Of course the result is incorrect because it's failing to discriminate by the table name.
Is this a bug or am I making another JPA noob mistake?
Thanks.

I was able to get similar behaviour doing similar JPQL. I have entered a bug in TopLink Essentials. 2465.
I did note that having the objects in memory made a significant difference (< .5 seconds for 1000 objects, each with 2 in the 1:M).

Similar Messages

  • Select from 2 tables with common key and than left join(unique result)

    Hi,
    I have 2 tables that have a common id (Customer_id) and I have a third table which contain her key consist of 3 column ( Customer_id , rms_customer_id,billind_tree_id) and have the manager_name field
    I am using a left join because not all the customers have a manager.
    I need to take only the manager_name field from the left join but the problem is that I am not getting a unique name results because the customer_id is not the primary key(only part of )
    so I have use the following :
    left join
    ( select * from ACCOUNT_Manager am where
    rms_customer_id <= all (select rms_customer_id from ACCOUNT_Manager am2 where
    am2.customer_id = am.customer_id )) am
    on c.ID = am.CUSTOMER_ID (C is one of the first 2 tables with the ID as key)
    Is there anyway more efficient of doing it ?
    Thanks

    Please consider the following when you post a question. This would help us help you better
    1. New features keep coming in every oracle version so please provide Your Oracle DB Version to get the best possible answer.
    You can use the following query and do a copy past of the output.
    select * from v$version 2. This forum has a very good Search Feature. Please use that before posting your question. Because for most of the questions
    that are asked the answer is already there.
    3. We dont know your DB structure or How your Data is. So you need to let us know. The best way would be to give some sample data like this.
    I have the following table called sales
    with sales
    as
          select 1 sales_id, 1 prod_id, 1001 inv_num, 120 qty from dual
          union all
          select 2 sales_id, 1 prod_id, 1002 inv_num, 25 qty from dual
    select *
      from sales 4. Rather than telling what you want in words its more easier when you give your expected output.
    For example in the above sales table, I want to know the total quantity and number of invoice for each product.
    The output should look like this
    Prod_id   sum_qty   count_inv
    1         145       2 5. When ever you get an error message post the entire error message. With the Error Number, The message and the Line number.
    6. Next thing is a very important thing to remember. Please post only well formatted code. Unformatted code is very hard to read.
    Your code format gets lost when you post it in the Oracle Forum. So in order to preserve it you need to
    use the {noformat}{noformat} tags.
    The usage of the tag is like this.
    <place your code here>\
    7. If you are posting a *Performance Related Question*. Please read
       {thread:id=501834} and {thread:id=863295}.
       Following those guide will be very helpful.
    8. Please keep in mind that this is a public forum. Here No question is URGENT.
       So use of words like *URGENT* or *ASAP* (As Soon As Possible) are considered to be rude.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • EclipseLink - oneToMany in lazy + join fetch

    Hi,
    I have a little problem with use a "join fetch".
    How use join fetch with @OneToMany lazy relations ?
    I have two objetcs : Object A has a list of objects B.
    A
    @oneToMany (Lazy relation)
    List<B> listB
    Now, I want load these 2 objects.
    I write a jpql like "select a from A a left join fetch a.listB where a.id=?"
    The sql generated is fine, I see the join between table A and B.
    BUT, when I try to access listB (outside session), I have a lazy exception.
    Why ?
    If (inside session) I access to listB, it's ok (with no more sql).
    So, I have wrote a method like that :
    public A findA(lond id){
    Query q = createQuery(select a from A a left join fetch a.listB where a.id=id");
    A = q.getSingleResult();
    A.getListB().size() -> to initialize relation (but non sql generated)
    return A;
    Someone has an idea ?
    Thanks for your responses.

    Hi,
    In fact my method findA... is inside a stateless bean.
    Outside session means that I call my method by a client application like that :
    Service service= (Service )context.lookup("xxxxx");
    A = service.findA();
    A.getListB().size;
    Exception is
    Exception [EclipseLink-7242] (Eclipse Persistence Services - 2.0.2.v20100323-r6872): org.eclipse.persistence.exceptions.ValidationException
    Exception Description: An attempt was made to traverse a relationship using indirection that had a null Session. This often occurs when an entity with an uninstantiated LAZY relationship is serialized and that lazy relationship is traversed after serialization. To avoid this issue, instantiate the LAZY relationship prior to serialization.
    For the version of eclipseLink, it's an ejb deployed on embedded weblogic with jdeveloper Studio Edition Version 11.1.1.3.0.
    It's JPA 1.0.
    Thanks for your response.
    Hope this help.
    Nicolas
    Edited by: 865770 on 15-juin-2011 8:12

  • LEFT Join not working

    Hi guys,
    I am not sure why the left join is not working.. when I try to use the and condition out of the left join condition. The database is relational but the requirement is for reporting. I have 2 user inputs and I should get the query results as explained below..
    Let me explain with the sample data.
    Table 1: PRTYPE (P)
    TYPEID CLASSID
    T001 CLS001
    T001 CLS002
    T001 CLS003
    T002 CLS002
    T003 CLS001
    Table 2: EMPLOYEE (E)
    EMPID NAME
    E001 Joe
    E002 Mark
    E003 Lucy
    Table 3: DETAILS (D)
    EMPID CLASSID STATUS
    E001 CLS001 NEW
    E001 CLS002 DONE
    E002 CLS001 NEW
    E002 CLS004 NEW
    Report1:
    Input: PRTYPE.TYPEID = T001, EMPID = E001
    Output:
    E.NAME E.EMPID P.TYPEID A.CLASSID D.STATUS
    JOE EMP001 T001 CLS001 NEW
    JOE EMP001 T001 CLS002 DONE
    JOE EMP001 T001 CLS003 BLANK
    Report2:
    PRTYPE.TYPEID = T003, EMPID = E003
    E.NAME E.EMPID P.TYPEID A.CLASSID D.STATUS
    LUCY E003 T003 CLS001 BLANK
    LUCY E003 T003 CLS004 BLANK
    When I use and condition in left join itself, it works but when I take it to the end of the sql using where p.typeid= T001 and E.EMPID = E001 I am not getting the left join results... It looks like Oracle doesn't like the condition at the end. I hope I am clear on explaining. Please share your experience on how to get it working..
    Thank you

    Hi,
    Welcome to the forum!
    user12118328 wrote:
    I am not sure why the left join is not working.. when I try to use the and condition out of the left join condition. The database is relational but the requirement is for reporting. I have 2 user inputs and I should get the query results as explained below..
    When I use and condition in left join itself, it works but when I take it to the end of the sql using where p.typeid= T001 and E.EMPID = E001 I am not getting the left join results... It looks like Oracle doesn't like the condition at the end. I hope I am clear on explaining. Please share your experience on how to get it working..I'm not sure what you mean. Why don't you post your query? You know, it will be easier for someone to tell you what you're doing wrong if they know what you're doing.
    Are you saying that you get the correct results when you have a cerain condition in an outer join, but that you get the wrong results if you put the exact same condition in the WHERE-clause?
    If so, keep the condition where it does what you want.
    You can usually move INNER join conditions around like that, but never OUTER join conditions.
    As Alex said, if you want help, post executable statement to create and populate your tables with a little sample data, as well as the output you want from that sample data, and your best attempt at a query.

  • Left Join In Webi Report

    Hi,
    I have a webi report wherein I use the custom SQL with left join. However when I run the query against the database( SQL Server 2005) I get the left  join to work . But when I run the report using the same SQL I do not see the left join implemented on the report .
    Wanted to have some guidance whether we do need to change anything on the Universe level/webi level to make the webi show the values with left join.  By default even after having custom sql I am seeing inner join.
    The procedures I have tried :
    Universe Level: In Paramters Tab: Set ANSI_SQL to yes  ( but it still does not work)
    Thank you,
    boe user

    Look at http://www.dagira.com/2010/08/17/handling-conditions-on-outer-joins/.
    Regards,
    Kuldeep

  • Inconsistent results with ANSI LEFT JOIN on 9iR2

    Is this a known issue? Is it solved in 10g?
    With the following data setup, I get inconsistent results. It seems to be linked to the combination of using LEFT JOIN with the NULL comparison within the JOIN.
    create table titles (title_id int, title varchar(50));
    insert into titles values (1, 'Red Book');
    insert into titles values (2, 'Yellow Book');
    insert into titles values (3, 'Blue Book');
    insert into titles values (4, 'Orange Book');
    create table sales (stor_id int, title_id int, qty int, email varchar(60));
    insert into sales values (1, 1, 1, '[email protected]'));
    insert into sales values (1, 2, 1, '[email protected]');
    insert into sales values (3, 3, 4, null);
    insert into sales values (3, 4, 5, '[email protected]');
    SQL&gt; SELECT titles.title_id, title, qty
    2 FROM titles LEFT OUTER JOIN sales
    3 ON titles.title_id = sales.title_id
    4 AND stor_id = 3
    5 AND sales.email is not null
    6 ;
    TITLE_ID TITLE QTY
    4 Orange Book 5
    3 Blue Book
    1 Red Book
    2 Yellow Book
    SQL&gt;
    SQL&gt; SELECT titles.title_id, title, qty
    2 FROM titles LEFT OUTER JOIN sales
    3 ON titles.title_id = sales.title_id
    4 AND 3 = stor_id
    5 AND sales.email is not null;
    TITLE_ID TITLE QTY
    2 Yellow Book 1
    4 Orange Book 5
    3 Blue Book
    1 Red Book
    It seems to matter what order I specify the operands stor_id = 3, or 3 = stor_id.
    In the older (+) environment, I would understand this, but here? I'm pretty sure most other databases don't care about the order.
    thanks for your insight
    Kevin

    Don't have a 9i around right now to test ... but in 10 ...
    SQL> create table titles (title_id int, title varchar(50));
     
    Table created.
     
    SQL> insert into titles values (1, 'Red Book');
     
    1 row created.
     
    SQL> insert into titles values (2, 'Yellow Book');
     
    1 row created.
     
    SQL> insert into titles values (3, 'Blue Book');
     
    1 row created.
     
    SQL> insert into titles values (4, 'Orange Book');
     
    1 row created.
     
    SQL> create table sales (stor_id int, title_id int, qty int, email varchar(60));
     
    Table created.
     
    SQL> insert into sales values (1, 1, 1, '[email protected]');
     
    1 row created.
     
    SQL> insert into sales values (1, 2, 1, '[email protected]');
     
    1 row created.
     
    SQL> insert into sales values (3, 3, 4, null);
     
    1 row created.
     
    SQL> insert into sales values (3, 4, 5, '[email protected]');
     
    1 row created.
     
    SQL> SELECT titles.title_id, title, qty
      2   FROM titles LEFT OUTER JOIN sales
      3   ON titles.title_id = sales.title_id
      4   AND stor_id = 3
      5   AND sales.email is not null
      6   ;
     
      TITLE_ID TITLE                                                     QTY
             4 Orange Book                                                 5
             3 Blue Book
             1 Red Book
             2 Yellow Book
     
    SQL>
    SQL> SELECT titles.title_id, title, qty
      2   FROM titles LEFT OUTER JOIN sales
      3   ON titles.title_id = sales.title_id
      4   AND 3 = stor_id
      5   AND sales.email is not null;
     
      TITLE_ID TITLE                                                     QTY
             4 Orange Book                                                 5
             3 Blue Book
             1 Red Book
             2 Yellow Book
    SQL> exit
    Disconnected from Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production
    With the Partitioning, OLAP and Data Mining options

  • Improve performance when using lots of left join

    when i run this query, it is taking *27 minutes* to execute. all keys have index. please help me to improve performance. i am using 11g.
    select distinct com.m1co as CO_ID,
    fsr.policy_number as POL_ID,
    com.M1AGNM as AGNCY_ID,
    cr.agent_code as AGT_ID,
    P.full_name as agent_name,
    ia.status_description as STS_CD,
    to_char(ia.bound_date, 'MM/DD/YYYY') as POL_INFC_DT,
    (fchgmm||'/'||fchgdd||'/'||fchgyy) as PAY_UP_DT ,
    (mcpdtm||'/'||mcpdtd||'/'||mcpdty) as pay_to_dt,
    (fexpmm||'/'||fexpdd||'/'||fexpyy) as MATURE_DT,
    ia.BILLING_FREQUENCY as PAY_MODE_CD,
    casc.MCPYCD as PAY_METHOD_CD,
    casc.MCPRMM as MODAL_PREM_AMT,
    casc.MCCRCD as POL_CUR,
    casc.MCNOPT as NFO_CD,
    cas.FINSTP as LINE_OF_BUSS,
    (MCPDTM||'/'||MCPDTD||'/'||MCPDTY) as BILL_TO_DT,
    com.M1LOCA as COLL_OFF,
    to_char(ia.bound_date, 'MM/DD/YYYY') as DELIVERY_DT,
    P.FULL_NAME as Serv_AGENT_NAME,
    casm.MWAGTN as SERV_AGT_CD,
    casc.MCNOPT as NFO_RULE,
    ia.STATUS_DESCRIPTION as POL_CSTAT_REASN_CD,
    SUBSTR(datesplit5(datesub),1,10) as APP_RECV_DT,
    to_char(ia.bound_date, 'MM/DD/YYYY') as ISSUE_DT,
    ia.SUM_ASSURED as CVG_FACE_AMT,
    p.IDENTITY_CARD_NUMBER as INSRD_CLI_CD
    FROM financial_services_role fsr
    left join channel_role cr on fsr.role_player_id=cr.role_player_id
    left join person p on (fsr.role_player_id=p.role_player_id and FSR.TYPE_DESCRIPTION IN ('AG','AGT'))
    left join ext_lsp_comagtm1 com on cr.agent_code=com.m1agno
    left join individual_agreement ia on fsr.policy_number =
    DECODE(ia.Business_Key_Contract_Number, NULL, ia.Business_Key_Policy_Number,ia.Business_Key_Contract_Number)
    left join EXT_LSP_CASCNTRM casc on (fsr.policy_number = casc.MCCNTR)
    left join ext_lsp_casbene cas on (fsr.policy_number = cas.fpolno and fbrcd = 0 )
    left join ext_lsp_casmwagt casm on (fsr.policy_number = casm.mwpoln and com.m1agnm = 'TAN')
    left join cdmtgt.EXT_LA_PTRNPF on (chdrnum = fsr.policy_number and
    BATCTRCDE = 'T600')
    WHERE com.m1co = 'IL';
    Thank you
    Edited by: 1000228 on Jun 5, 2013 10:36 AM

    HOW To Make TUNING request
    SQL and PL/SQL FAQ
    SELECT DISTINCT com.m1co                             AS CO_ID,
                    fsr.policy_number                    AS POL_ID,
                    com.m1agnm                           AS AGNCY_ID,
                    cr.agent_code                        AS AGT_ID,
                    ' '                                  AS AGNCY_ID_2,
                    ' '                                  AS AGT_ID_2,
                    ' '                                  AS AGT_ID_2_NAME,
                    P.full_name                          AS agent_name,
                    ia.status_description                AS STS_CD,
                    To_char(ia.bound_date, 'MM/DD/YYYY') AS POL_INFC_DT,
                    ( fchgmm
                      ||'/'
                      ||fchgdd
                      ||'/'
                      ||fchgyy )                         AS PAY_UP_DT,
                    ( mcpdtm
                      ||'/'
                      ||mcpdtd
                      ||'/'
                      ||mcpdty )                         AS pay_to_dt,
                    ( fexpmm
                      ||'/'
                      ||fexpdd
                      ||'/'
                      ||fexpyy )                         AS MATURE_DT,
                    ia.billing_frequency                 AS PAY_MODE_CD,
                    casc.mcpycd                          AS PAY_METHOD_CD,
                    casc.mcprmm                          AS MODAL_PREM_AMT,
                    casc.mccrcd                          AS POL_CUR,
                    casc.mcnopt                          AS NFO_CD,
                    cas.finstp                           AS LINE_OF_BUSS,
                    ' '                                  AS REGLR_OR_SCHEDL_TOPUP,
                    ' '                                  AS POLICY_LAPSED_DT,
                    ( mcpdtm
                      ||'/'
                      ||mcpdtd
                      ||'/'
                      ||mcpdty )                         AS BILL_TO_DT,
                    com.m1loca                           AS COLL_OFF,
                    To_char(ia.bound_date, 'MM/DD/YYYY') AS DELIVERY_DT,
                    P.full_name                          AS Serv_AGENT_NAME,
                    casm.mwagtn                          AS SERV_AGT_CD,
                    casc.mcnopt                          AS NFO_RULE,
                    ia.status_description                AS POL_CSTAT_REASN_CD,
                    Substr(Datesplit5(datesub), 1, 10)   AS APP_RECV_DT,
                    To_char(ia.bound_date, 'MM/DD/YYYY') AS ISSUE_DT,
                    ia.sum_assured                       AS CVG_FACE_AMT,
                    '0'                                  AS BASE_CVG_NUM,
                    p.identity_card_number               AS INSRD_CLI_CD
    FROM   financial_services_role fsr
           left join channel_role cr
                  ON fsr.role_player_id = cr.role_player_id
           left join person p
                  ON ( fsr.role_player_id = p.role_player_id
                       AND FSR.type_description IN ( 'AG', 'AGT' ) )
           left join ext_lsp_comagtm1 com
                  ON cr.agent_code = com.m1agno
           left join individual_agreement ia
                  ON fsr.policy_number = Decode(ia.business_key_contract_number,
                                         NULL,
           ia.business_key_policy_number,
                                         ia.business_key_contract_number)
           left join ext_lsp_cascntrm casc
                  ON ( fsr.policy_number = casc.mccntr )
           left join ext_lsp_casbene cas
                  ON ( fsr.policy_number = cas.fpolno
                       AND fbrcd = 0 )
           left join ext_lsp_casmwagt casm
                  ON ( fsr.policy_number = casm.mwpoln
                       AND com.m1agnm = 'TAN' )
           left join cdmtgt.ext_la_ptrnpf
                  ON ( chdrnum = fsr.policy_number
                       AND batctrcde = 'T600' )
    WHERE  com.m1co = 'IL';

  • Getting One to Many Left Join to be in One Result Row...

    11G APEX 4.2
    At this time I don't have access to make a view or anything like that. Just select access to the data.
    BEGIN
    for i in (
    SELECT CAA.NODE_NAME THENODE,CNF.FEATURE_TYPE CNFFT from CMS.CMS_APP_ASSIGN "CAA"
    LEFT JOIN CMS.CMS_NODE_FEATURE "CNF" on CAA.NODE_NAME=CNF.NODE_NAME
    WHERE CAA.NODE_APP = :WHICHAPP and CAA.REMOVE_DT is NULL)
    LOOP
    dbms_output.put_line(i.THENODE||'--'||i.CNFFT||'<BR>');
    END LOOP;
    END;
    When this returns there is a row for each of the left joins.
    server1--CPUCount<BR>
    server1--ContactInfo<BR>
    server1--ContactInfo<BR>
    server1--ContactInfo<BR>
    server2--CPUCount<BR>
    What I would like to do it just have one row:
    NODENAME
    CPUCount
    Contactinfo
    Contact Info
    Contact Info
    ETC
    server1
    value1
    value2
    value4
    c
    Thanks

    Hi,
    Taking 1 column from N rows, and transforming that into N columns on 1 row is called Pivoting.
    The forum FAQ has a page on this subject.  See https://forums.oracle.com/message/9362005#9362005
    While you're in the Forum FAQ, also see https://forums.oracle.com/message/9362002

  • Help with sql - Left Join

    Hi,
    Below are the details of what I am attempting to do.
    DB version: 10.2.0.4.0
    Sample Table Definition
    create table t_cnf
    conf_id number,
    conf_value number,
    conf_cat_id number,
    actv_flg    char(1)
    create table t_int_act
    int_acc_id   number,
    frst_mrch_id number,
    create_date  date
    create table t_int_act_cast
    int_acc_id   number,
    cast_id      number
    create t_cast_alt_nmnt
    cas_alt_nmt_id number,
    cas_alt_id     number,
    cast_id        number,
    enrl_flg       char(1),
    src_id         number
    );Sample Data
    insert into t_cnf values (1, 78965098, 12, 'Y');
    insert into t_cnf values (1, 78965098, 13, 'Y');
    insert into t_int_act values (234,78965098, trunc(sysdate) - 1);
    insert into t_int_act_cast values (234, 560432);
    insert into t_cas_alt_nmnt values (1, 2, 560432, 'Y', 2); Need to fetch all cast_ids that are not in t_cast_alt_nmnt or cast_ids that are present in t_cast_alt_nmnt but have t_cast_alt_nmnt.enrl_flg = 'N' and t_cast_alt_nmnt.cast_alt_id in (2,3) and t_cast_alt_nmnt.src_id <> 2
    for t_int_act.frst_mrch_ids matching t_cnf.conf_vale
    Records fetch will insert a record into t_cast_alt_nmnt with css_alt_id 2 or 3 (determined by pe_or_pd).
    I attempted to write below sql. This works fine when cast_id does not exists in t_cast_alt_nmnt but will not return correct results when there is a record in t_cast_alt_nmnt matching above criteria.
    select
        iac.cast_id                            cast_id,
        sysdate                                upd_date,               
        case
            when c.conf_cat_id = 12 then 2
            when c.conf_cat_id = 13 then 3
        end
            pe_or_pd           
    from
        t_cnf                  c
    join    
        t_int_act          ia
    on
        ia.frst_mrch_id = c.conf_value
    join              
        t_int_act_cast iac
    on
        ia.int_acc_id = iac.int_acc_id
    left join       
        t_cast_alt_nmnt     can
    on
        can.cast_id = iac.cast_id     and
        can.enrl_flg = 'N'            and
        can.cas_alt_id in (2,3)       and
        can.src_id <> 2      
    where                 
        c.conf_cat_id              in (12,13)                           and
        c.actv_flg                 = 'Y'                                and
        -- Fetch all new customer created day before.   
        ia.create_date             >= trunc(sysdate) - 1                   
        Expected results
    With no cast_id record in t_cast_alt_nmnt
    cast_id upd_date pe_or_pd
    560432 4/19/2012 2
    560432 4/19/2012 3
    With cast_id record in t_css_alt_nmt (insert provided)
    cast_id upd_date pe_or_pd
    560432 4/19/2012 3
    Appreciate your help
    Edited by: user572194 on Apr 19, 2012 1:04 PM

    Thanks Frank for taking time to look into this and providing sql. I will test is against use cases (mentioned below).
    And I apologize for the typos. I had to change table and column names as it is policy of our company not to post data model details in public forums.
    Requirement:
    1. New cast ids will be added daily and these will get inserted into t_int_act and t_int_act_cas
    2. t_cnf has 2 conf_cat_id configured 12 and 13 and each conf_cat_id will have same conf_values (same as t_int_act.frst_mrch_id) but actv_flg might be different (set to N for 12 and Y for 13). Need to fetch only active ones
    3. t_cas_alt_nmnt will have cast_ids that are enrolled to receive certain mails if enrl_flg is Y for these. Not all cast_ids will have record in this table.
    When a cast_id is enrolled by customer service, a record will get inserted with src_id = 2.
    4. Requirement is to enroll new cast_ids created with frst_mrch_id matching t_cnf.conf_value where conf_cat_id in (12,13)
    Match criteira:
    If t_int_act_cas.cast_id exists in t_cas_alt_nmnt and have enrl_flg = 'Y' for cas_alt_id = 2 then
    insert record with same cast_id, enrl_flg = 'Y' and css_alt_id = 3
    If t_int_act_cas.cast_id exists in t_cas_alt_nmnt and have enrl_flg = 'Y' for cas_alt_id = 3 then
    insert record with same cast_id, enrl_flg = 'Y' and css_alt_id = 2
    If t_int_act_cas.cast_id exists in t_cas_alt_nmnt and have enrl_flg = 'N' for cas_alt_id in (2,3) and src_id = 2 then
    Ignore this record.
    if t_int_act_cas.cast_id not exists in t_cas_alt_nmnt then
    insert 1 record each with cast_id, enrl_flg = 'Y' for css_alt_id 2 and 3
    Hope above explanation makes sense.
    By the way I tried below sql. Yet to test it for all use cases but it worked for the last two.
    Note on PE_OR_PD column. I am just using this column to write separate inserts for css_alt_id 2 and 3.
    select
         cast_id,
         upd_date,
         pe_or_pd
    from    
         (select
                    iac.cast_id                        cast_id,
                    sysdate                            upd_date,
                    case
                        when c.conf_cat_id = 12 and can.cas_alt_id in (2,3) and enrl_flg = 'Y' then null
                        when c.conf_cat_id = 13 and can.cas_alt_id in (2,3) and enrl_flg = 'Y' then null
                        when c.conf_cat_id = 12 and nvl(can.cas_alt_id,2) = 2 and nvl(can.enrl_flg,'Y') = 'N' and can.src_id <> 2 then 'PE'
                        when c.conf_cat_id = 13 and nvl(can.cas_alt_id,3) = 3 and nvl(can.enrl_flg,'Y') = 'N' and can.src_id <> 2 then 'PD'       
                        when c.conf_cat_id = 12 and nvl(can.cas_alt_id,2) = 2 and nvl(can.enrl_flg,'Y') = 'Y' then 'PE'                                                                     
                        when c.conf_cat_id = 13 and nvl(can.cas_alt_id,3) = 3 and nvl(can.enrl_flg,'Y') = 'Y' then 'PD'                                                          
                    end
                        pe_or_pd              
                from
                    t_cnf              c,   
                    t_int_act          ia,      
                    t_intl_act_cus     iac,
                    t_cas_alt_nmnt     can              
                where
                    c.conf_value               = ia.frst_mrch_id               and
                    ia.internal_account_id     = iac.int_act_id                and 
                    can.cast_id(+)             = iac.cast_id                   and                               
                    c.conf_cat_id              in (12,13)                      and
                    c.actv_flg                 = 'Y'                           and
                    -- Fetch all new customer created after last run.   
                    ia.create_date             >= trunc(sysdate) - 1                                                                     
         ) enrl_cust
    where
        pe_or_pd is not null               
                    ;

  • Left join query prob

    Hi,
    I have one ejbql for selecting records from one table which are not in the other table.There is actually records in the data base but by using this query it is retrieving noting . The corresponding pl/sql query is working fine and it is retrieve correct result .what is wrong with my query.. Plz help me to correct this query...
    My ejbql is below...
    EJB-QL
    SELECT C.name FROM person C LEFT JOIN C.address FC WHERE C.id.name= FC.id.name AND FC.id.pcode IS NULL
    There is no result while executing this query. The correspoinding pl sql query is
    PL/SQL
    SELECT e_person .* FROM e_person ep LEFT JOIN e_address ea ON ep .name= ea .name WHERE ea.pcode IS NULL
    plz help ...
    Thanks in advance
    Ani

    Enable logging and include the SQL generated for the JPQL.
    JPQL will also join via the primary/foreign key define in the mapping when you do C.address, if this is not name then you may be joining by something else. You could just declare the Address independent of the Employee if you do not wish to join by primary key (although this seems odd).
    -- James : http://www.eclipselink.org

  • Left Join query: revisited... I have to explain at user meeting tomm. pls..

    Hi Everyone,
    Can someone pls shed some light on the situation below
    I am understanding alot of what Michael and Rod wrote.... with my prev. post of LEFT JOIN and testing for
    not null and doing a double Boolean OR etc.
    - but- AM NOT understanding why the IS NOT NULL works, without the double boolean OR
    Pls help... have to explain what left join means to user tomm. I'm going to demo the query below and
    not the one with the double boolean OR bec. maybe too much info to present at one sitting. tx, sandra
    =====================
    the query below is left joining the STUDENT table to
    HOLD table.
    The HOLD table - contains rows for students who have holds on their record.
    a student can have more than one hold (health, HIPAA, basic life saving course)
    BUT, for this query: I'm only interested that a hold exists, so I'm choosing MAX on hold desc.
    Selecting a MAX, helps me, bec. it reduces my join to a 1 to 1 relationship, instead of
    1 to many relationship.
    Before I posted this thread at all, the LEFT JOIN below testing for IS NOT NULL worked w/o
    me having to code IS NOT NULL twice....
    Is that because, what's happening "behind the scenes" is that a temporary table containing all max rows is being
    created, for which Discoverer has no predefined join instructions, so it's letting me do a LEFT JOIN and have
    the IS NOT NULL condition.
    I would so appreciate clarification. I have a meeting on Tues, for which I have to explain LEFT JOINS to the user
    and how they should create a query. I need to come up with rules.
    If I feel "clear", I asked my boss to buy Camtasia videocast software to create a training clip for user to follow.
    Also, if any Banner user would like me to email the DIS query to run on their machine, I would be glad to do so.
    thx sooo much, Sandra
    SELECT O100384.ACADEMIC_PERIOD, O100255.ID, O100384.ID, O100255.NAME, O100384.NAME, O100255.PERSON_UID, O100384.PERSON_UID, MAX(O100255.HOLD_DESC)
    FROM ODSMGR.HOLD O100255, ODSMGR.STUDENT O100384
    WHERE ( ( O100384.PERSON_UID = O100255.PERSON_UID(+) ) ) AND ( O100384.ACADEMIC_PERIOD = '200820' )
    GROUP BY O100384.ACADEMIC_PERIOD, O100255.ID, O100384.ID, O100255.NAME, O100384.NAME, O100255.PERSON_UID, O100384.PERSON_UID
    HAVING ( ( MAX(O100255.HOLD_DESC(+)) ) IS NOT NULL )
    ORDER BY O100384.NAME ASC

    Hi,
    OK, I will try to explain this. When you outer join table B to table A then the rows in table A which do not match any rows in table B will returned with NULL in the columns from the table B.
    Oracle uses the syntax ( +) for outer joins. Now if you add another condition using the ( +) syntax (as shown below) the condition will be processed before the table is joined. Therefore if table A does not match any rows in table B which have col2=1 then the row from table A will be returned with NULLs for the table B columns.
    SELECT A.col1, B.col1
    FROM A, B
    WHERE A.col1 = B.col1( +)
    AND B.col2( +)=1
    Now, if the condition B.col2=1 was used instead then the condition would be processed after the join and therefore the rows from table A that were joined to table B but did not meet the condition would not be returned by the query.
    This applies to a WHERE clause and to the HAVING clause, but with one exception. If you use the ( +) within a group function in a HAVING clause then the ( +) will have no affect because the condition must be processed after group by and group by can only be processed after the join. Therefore MAX(B.col2( +)) = 1 is processed after the join even through it uses the ( +) syntax.
    You cannot use an OR or an IN with the ( +) syntax because the meaning of the OR in this situation is ambiguous, is the OR done before or after the join. A query with an OR or IN in an outer will fail with an Oracle ORA-01719 error. Discoverer recognises this situation and removes the ( +) so that the error does not occur. However, without the ( +) the conditions are processed after the join.
    Using the ( +) with IS NULL, e.g. col2( +) IS NOT NULL works in the same way. You just have to remember that the col2( +) could be NULL as a result of the outer join and therefore if the condition is processed after the query then the IS NOT NULL will remove the outer joined rows.
    Hope that is clear.
    Rod West

  • Oracle outer join strange results (at least for me)

    Hi there,
    I want to show you a problem I saw to a client site.
    Oracle 9.2.0.8.0
    SunOS 5.9 (but I'm unable to check installed patch)
    The query is quite simple:
    SELECT *
      FROM     (SELECT /*+ NO_MERGE */
                      DISTINCT col1,col2
                  FROM Tab1
                 WHERE status = 'L') a
           LEFT JOIN
               (SELECT col1,
                       col2,
                       1 as flag_match
                  FROM tab2 a
                 WHERE     a.action IN ('I', 'U')
                       AND NVL (a.col3, 'D') IN ('I', 'U')
                       AND NVL (a.col4, '?') NOT IN ('V', 'P', 'Q')) b
           ON (b.col1 = a.col1 AND b.col2 = a.col2)The expected result is (obvious?):
    a.Col1   a.Col2   b.Col1   b.Col2   flag_match
    X          Y         NULL    NULL     NULL
    A          B         A         B          1What we get is:
    a.Col1   a.Col2   b.Col1   b.Col2   flag_match
    X          Y         NULL    NULL     NULL
    A          B         A         B          NULLThis looks wrong to me.
    If we check with a SELECT COUNT(*) the result of the query, using something like this:
    SELECT COUINT(*) FROM (
    SELECT *
      FROM     (SELECT /*+ NO_MERGE */
                      DISTINCT col1,col2
                  FROM Tab1
                 WHERE status = 'L') a
           LEFT JOIN
               (SELECT col1,
                       col2,
                       1 as flag_match
                  FROM tab2 a
                 WHERE     a.action IN ('I', 'U')
                       AND NVL (a.col3, 'D') IN ('I', 'U')
                       AND NVL (a.col4, '?') NOT IN ('V', 'P', 'Q')) b
           ON (b.col1 = a.col1 AND b.col2 = a.col2)
    WHERE flag_match...We got these results:
    with FLAG_MATCH IS NULL, 1000 rows
    with FLAG_MATCH IS NOT NULL, 900 rows
    without the where on FLAG_MATCH, 1000 rows
    What you think? Ever seen something like this?
    Thank you in advance.
    Antonio

    Hi Antonio,
    running the query as you have posted, you should not get the result NULL under column flag_match when b.col1 is not NULL.
    Unless a bug but I doubt it.
    Could you please post some sample data to be able to reproduce the problem?
    Data can be posted also as WITH statement in this way:
    WITH tab1(col1, col2, status) AS
       SELECT 'X', 'Y', 'L' FROM DUAL UNION ALL
       SELECT 'A', 'B', 'L' FROM DUAL
    , tab2(col1, col2, col3, col4, action) as
       SELECT 'A', 'B', 'I', 'X', 'I' FROM DUAL
    SELECT *
      FROM     (SELECT /*+ NO_MERGE */
                      DISTINCT col1,col2
                  FROM Tab1
                 WHERE status = 'L') a
           LEFT JOIN
               (SELECT col1,
                       col2,
                       1 as flag_match
                  FROM tab2 a
                 WHERE     a.action IN ('I', 'U')
                       AND NVL (a.col3, 'D') IN ('I', 'U')
                       AND NVL (a.col4, '?') NOT IN ('V', 'P', 'Q')) b
           ON (b.col1 = a.col1 AND b.col2 = a.col2)
    COL1 COL2 COL1_1 COL2_1 FLAG_MATCH
    A    B    A      B               1
    X    Y                            Also try to execute the statement above to see if you are experiencing the same problem.
    Edit:
    I've seen the second part of your post:
    with FLAG_MATCH IS NULL, 1000 rows
    with FLAG_MATCH IS NOT NULL, 900 rows
    without the where on FLAG_MATCH, 1000 rowsand I have to say that is looks like a bug. Could you try grouping by flag_match?
    SELECT flag_match, COUNT(*) FROM (
    SELECT *
      FROM     (SELECT /*+ NO_MERGE */
                      DISTINCT col1,col2
                  FROM Tab1
                 WHERE status = 'L') a
           LEFT JOIN
               (SELECT col1,
                       col2,
                       1 as flag_match
                  FROM tab2 a
                 WHERE     a.action IN ('I', 'U')
                       AND NVL (a.col3, 'D') IN ('I', 'U')
                       AND NVL (a.col4, '?') NOT IN ('V', 'P', 'Q')) b
           ON (b.col1 = a.col1 AND b.col2 = a.col2)
    GROUP by flag_matchRegards.
    Al
    Edited by: Alberto Faenza on Dec 18, 2012 2:49 PM

  • 3 tables with left joins - bug?

    Hello,
    i am making query where i encounter problem with left join in oracle. I am using oracle 10g and i prepare simple test case.
    he is testing tables and datas - really simple i think:
    drop table t1;
    drop table t2;
    drop table t3;
    create table t1 (a number not null);
    create table t2 (a number, b number);
    create table t3 (b number);
    insert into t3 values (1);
    insert into t3 values (2);
    insert into t3 values (3);
    insert into t1 (a) values (1);
    insert into t2 (a,b) values (1,1);
    insert into t1 (a) values (2);
    insert into t2 (a,b) values (2, null);
    insert into t1 (a) values (3);
    insert into t1 (a) values (4);
    insert into t2 (a,b) values (4,1);
    insert into t1 (a) values (5);
    insert into t2 (a,b) values (5,3);
    and now query with left joins:
    select
    t1.a
    , t2.a, t2.b
    , t3.b
    from
    t1, t2, t3
    where
    t1.a = t2.a (+)
    and t2.b = t3.b (+)
    and t3.b is null
    order by t1.a
    i get two rows as result:
    A A_1 B B_1
    2 2 null null      
    3 null null null                
    i expect these rows but when i change my query - i dont want get back t3.b column:
    select
    t1.a
    , t2.a, t2.b
    /* , t3.b*/
    from
    t1, t2, t3
    where
    t1.a = t2.a (+)
    and t2.b = t3.b (+)
    and t3.b is null
    order by t1.a
    i get only one row
    A A_1 B
    2 2 null
    My question is simple how can i only by changing columns getting back change number of returned rows? I must say i dont expect these result i expect two rows again.
    Thanks for help.

    BluShadow wrote:
    I think I know what you are getting at.
    By testing for null on t3.b when you aren't selecting the column, you are enforcing oracle to perform the join through t2 onto t1, but Oracle can't join because t2 has no matching row (although it's outer joined to t1) and therefore, for the one row it can't actually determine if t3.b is null or not, so that row can't match the conditions in a "true" sense and be displayed. If you select the column then oracle can test its nullness ok. (Perhaps this is a bug, I don't know, it's just how I know it works)If you get different results only by changing the projection part of the query this is a bug and nothing else. I can't reproduce using Oracle 10g XE, I get in both cases shown the expected two rows.
    What versions are you using to test this?
    SQL>
    SQL> select * from v$version
      2  where rownum <= 1;
    BANNER
    Oracle Database 10g Express Edition Release 10.2.0.1.0 - Product
    SQL>
    SQL> drop table t1 purge;
    Table dropped.
    SQL> drop table t2 purge;
    Table dropped.
    SQL> drop table t3 purge;
    Table dropped.
    SQL>
    SQL> create table t1 (a number not null);
    Table created.
    SQL> create table t2 (a number, b number);
    Table created.
    SQL> create table t3 (b number);
    Table created.
    SQL>
    SQL> insert into t3 values (1);
    1 row created.
    SQL> insert into t3 values (2);
    1 row created.
    SQL> insert into t3 values (3);
    1 row created.
    SQL>
    SQL> insert into t1 (a) values (1);
    1 row created.
    SQL> insert into t2 (a,b) values (1,1);
    1 row created.
    SQL>
    SQL> insert into t1 (a) values (2);
    1 row created.
    SQL> insert into t2 (a,b) values (2, null);
    1 row created.
    SQL>
    SQL> insert into t1 (a) values (3);
    1 row created.
    SQL>
    SQL> insert into t1 (a) values (4);
    1 row created.
    SQL> insert into t2 (a,b) values (4,1);
    1 row created.
    SQL>
    SQL> insert into t1 (a) values (5);
    1 row created.
    SQL> insert into t2 (a,b) values (5,3);
    1 row created.
    SQL>
    SQL> commit;
    Commit complete.
    SQL>
    SQL> select t1.a
      2       , t2.a, t2.b
      3       , t3.b
      4  from
      5         t1 left outer join t2 on (t1.a = t2.a)
      6            left outer join t3 on (t2.b = t3.b)
      7  where t3.b is null
      8  order by t1.a;
             A          A          B          B
             2          2
             3
    SQL>
    SQL> select t1.a
      2       , t2.a, t2.b
      3  --     , t3.b
      4  from
      5         t1 left outer join t2 on (t1.a = t2.a)
      6            left outer join t3 on (t2.b = t3.b)
      7  where t3.b is null
      8  order by t1.a;
             A          A          B
             2          2
             3
    SQL>Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/

  • Left join and where clause with not equal ( ) returns too many rows

    Say I have something like this
    Table A
    =========
    Id
    OrderNum
    Date
    StoreName
    AddressKey
    Table B
    ========
    Id
    StreetNumber
    City
    State
    select a.* from [Table A] a
    left join [Table B] b on a.AddressKey = b.Id
    where a.StoreName <> 'Burger place'
    The trouble is that the above query still returns rows that have StoreName = 'Burger place'
    One way Ive handled this is to use a table expression, select everything into that, then select from the CTE and apply the filter there.  How could you handle it in the same query however?

    Hi Joe,
    Thanks for your notes.
    INT SURROGATE PRIMARY KEY provides a small footprint JOIN ON column. Hence performance gain and simple JOIN programming.  In the Addresses table, address_id is 4 bytes as opposed to 15 bytes san. Similarly for the Orders table.
    INT SURROGATE PRIMARY KEY is a meaningless number which can be duplicated at will in other tables as FOREIGN KEY.  Having a meaningful PRIMARY KEY violates the RDBMS basics about avoiding data duplication.  If I make CelebrityName (Frank Sinatra)
    a PRIMARY KEY, I have to duplicate "Frank Sinatra" as an FK wherever it needed as opposed to duplicating SURROGATE PRIMARY KEY CelebrityID (79) a meaningless number.
    This is how we design in SQL Server world.
    QUOTE from Wiki: "
    Advantages[edit]
    Immutability[edit]
    Surrogate keys do not change while the row exists. This has the following advantages:
    Applications cannot lose their reference to a row in the database (since the identifier never changes).
    The primary or natural key data can always be modified, even with databases that do not support cascading updates across related
    foreign keys.
    Requirement changes[edit]
    Attributes that uniquely identify an entity might change, which might invalidate the suitability of natural keys. Consider the following example:
    An employee's network user name is chosen as a natural key. Upon merging with another company, new employees must be inserted. Some of the new network user names create conflicts because their user names were generated independently (when the companies
    were separate).
    In these cases, generally a new attribute must be added to the natural key (for example, an
    original_company column). With a surrogate key, only the table that defines the surrogate key must be changed. With natural keys, all tables (and possibly other, related software) that use the natural key will have to change.
    Some problem domains do not clearly identify a suitable natural key. Surrogate key avoids choosing a natural key that might be incorrect.
    Performance[edit]
    Surrogate keys tend to be a compact data type, such as a four-byte integer. This allows the database to query the single key column faster than it could multiple columns. Furthermore a non-redundant distribution of keys causes the resulting
    b-tree index to be completely balanced. Surrogate keys are also less expensive to join (fewer columns to compare) than
    compound keys.
    Compatibility[edit]
    While using several database application development systems, drivers, and
    object-relational mapping systems, such as
    Ruby on Rails or
    Hibernate, it is much easier to use an integer or GUID surrogate keys for every table instead of natural keys in order to support database-system-agnostic operations and object-to-row mapping.
    Uniformity[edit]
    When every table has a uniform surrogate key, some tasks can be easily automated by writing the code in a table-independent way.
    Validation[edit]
    It is possible to design key-values that follow a well-known pattern or structure which can be automatically verified. For instance, the keys that are intended to be used in some column of some table might be designed to "look differently from"
    those that are intended to be used in another column or table, thereby simplifying the detection of application errors in which the keys have been misplaced. However, this characteristic of the surrogate keys should never be used to drive any of the logic
    of the applications themselves, as this would violate the principles of
    Database normalization"
    LINK: http://en.wikipedia.org/wiki/Surrogate_key
    Kalman Toth Database & OLAP Architect
    SQL Server 2014 Database Design
    New Book / Kindle: Beginner Database Design & SQL Programming Using Microsoft SQL Server 2014

  • JPA OnetoMany  QUERY LEFT JOIN BUG

    Using JPA in JDev 10.1.3.1.0.3984
    Database: Firebird 1.51LI-V1.5.3.4870 Firebird 1.5/tcp
    Driver: Jaybird JCA/JDBC driver Version: 2.1
    TopLink, version: Oracle TopLink Essentials - 2006.8 (Build 060829)
    If I use normal JOIN it works.
    On LEFT JOIN I get a {oj [/b] before the table name and a [b]} at the end.
    public class Cliente{
        @OneToMany(mappedBy = "cliente")
        @JoinColumn(name = "CDCLIENTE", referencedColumnName = "CDCLIENTEREQUISITANTE")
        private List<Requisicao> requisicoes;
    public class Requisicao
        @ManyToOne
        @JoinColumn(name = "CDCLIENTEREQUISITANTE", referencedColumnName = "CDCLIENTE")
        private Cliente cliente;
    EntityManager em = getEntityManager();
    String sql = "SELECT c FROM Cliente c LEFT JOIN c.requisicoes req";
    Query q = em.createQuery(sql);
    List rs = q.getResultList();Result SQL:
    SELECT DISTINCT t0. <OMITTED> FROM {oj [/b]CLIENTE t0 LEFT OUTER JOIN REQUISICAO t1 ON (t1.CDCLIENTEREQUISITANTE = t0.CDCLIENTE)[b]}

    You cannot define an ON clause with Criteria, nor JPQL.
    Perhaps you can reword the query to avoid needing an ON clause.
    What is the query you want to do (in english)?
    Can you just use an OR in the where clause?
    There is a enhancement request to have ON clause support added, please vote for it.
    https://bugs.eclipse.org/bugs/show_bug.cgi?id=312146
    James : http://www.eclipselink.org

Maybe you are looking for