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 ?
ThanksPlease 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 -
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 youHi,
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. -
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 userLook 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> 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
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
KevinDon'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 AMHOW 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
ThanksHi,
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 -
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 PMThanks 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
; -
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
AniEnable 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 -
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 ASCHi,
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.
AntonioHi 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
-
HT1711 It wont let me download my music for 90 days. why?
Hi, Just recently my Iphone 4S music library had cleared itself. I then turned my phone off then back on thinking it may have been aa glitch. I then turned it back on and went to my Itunes store a and went to my purchases. Afterwards I had chose the
-
=== Hi I bought an iMac a week ago and installed Firefox via Safari. It worked fine for a while but, after a recently switching on, it won't connect to the web whereas Safari has no problems. I've tried following the Firefox Help, looking into the iM
-
All SAP Gurus, Can we maintain Info records for service PO? Regards,
-
IOS 8 and high temperature warning
I have an iPhone 4S and the day it came out iOS update 8 upgraded and now I get not even be using the phone a warning that says "iPhone temperature must fall before you can use it." Appears very often and only lets me make emergency calls. I need som
-
Error In WorkBook Bex Analyzer : Messages available
Hello Experts, When i open a Workbook, I have this message in the status bar: "Messages available; double-click to display them" When I double click, I have a pop-up window with warning "there is a condition.., results row supress..." Our client don'