Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 316144 - CriteriaBuilderImpl Method: and() in conjunction with isNull()/isNotNull() does not work correctly
Summary: CriteriaBuilderImpl Method: and() in conjunction with isNull()/isNotNull() do...
Status: CLOSED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 7
: P2 normal with 5 votes (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard: submitted_patch
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-08 10:42 EDT by Michael CLA
Modified: 2022-06-09 10:22 EDT (History)
7 users (show)

See Also:


Attachments
java code snippet describing the problem (2.42 KB, application/octet-stream)
2010-06-08 10:45 EDT, Michael CLA
no flags Details
Propsed fix (5.64 KB, application/octet-stream)
2010-11-04 10:28 EDT, Tom Ware CLA
no flags Details
Updated Patch (5.64 KB, patch)
2010-11-04 11:37 EDT, Tom Ware CLA
no flags Details | Diff
Updated Patch (5.64 KB, patch)
2010-11-04 11:40 EDT, Tom Ware CLA
no flags Details | Diff
Updated Patch (6.53 KB, patch)
2010-11-04 11:43 EDT, Tom Ware CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael CLA 2010-06-08 10:42:10 EDT
Build Identifier: 2.0.2.v20100323-r6872

when using isNull() and isNotNull() the and() method does not correctly and-together two parameters.

e.g. little code snippet:

criteriaList.add(builder.isNotNull(from.get(Rating_.ratOutputValue))); 
criteriaList.add(builder.isNotNull(from.get(Rating_.ratOutputValueunitId)));
criteriaList.add(builder.isNull(outerJoin.get(SomeEntity_.someId)));
Predicate criteria = builder.and(criteriaList.toArray(new Predicate[0]));
cq.select(from).where(criteria);

in the resulting SQL-String only one criteria is queried (3 were expected)

If the criteria's are built with the "less-readable" notEqual() or equal() all 3 parameters are queried by the SQL Query.

more details in the attached snippet

Reproducible: Always

Steps to Reproduce:
1. use the CriteriaBuilder
2.
3.
Comment 1 Michael CLA 2010-06-08 10:45:02 EDT
Created attachment 171409 [details]
java code snippet describing the problem
Comment 2 Vitor Souza CLA 2010-06-11 10:26:21 EDT
I ran into the same bug, but combining isNull (or isNotNull) with equals. It considers the equals and ignores the isNull (or isNotNull).

I described my experience with this bug here, if anyone is interested: 

http://stackoverflow.com/questions/3014313/jpa-2-criteria-api-why-is-isnull-being-ignored-when-in-conjunction-with-equal/3019159#3019159

In a comment to my post in that forum, another forum member said he tested with Hibernate Entity Manager 3.5.1 and it worked as expected.
Comment 3 Tom Ware CLA 2010-06-15 11:14:08 EDT
Setting target and priority.  See the following page for details of the meanings of these:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines
Comment 4 Mikael Nousiainen CLA 2010-08-25 10:26:28 EDT
This is basic functionality that I would expect to work.

Has anything been done to fix this?
Will the fix be included in the next "maintenance release"? (2.1.1 perhaps?)
Comment 5 Tom Ware CLA 2010-08-25 10:36:15 EDT
2.1.1 is complete and will be shipped shortly.  The fix for this issue is not included in that release.

I encourage the community to keep voting for this bug as votes are one of our main criteria for choosing community submitted bugs for our patch releases.
Comment 6 pj.chartre CLA 2010-09-02 08:16:58 EDT
I think the correction of this issue is very important and usefull for many usage.
I've tried to fix it by commenting some optimization code in CriteriaBuilderImpl.and().

    public Predicate and(Expression<Boolean> x, Expression<Boolean> y){
        CompoundExpressionImpl xp = null;
        CompoundExpressionImpl yp = null;
        
        
        if (((InternalExpression)x).isExpression()){
            xp = (CompoundExpressionImpl)this.isTrue(x);
        }else{
            xp = (CompoundExpressionImpl)x;
        }
        if (((InternalExpression)y).isExpression()){
            yp = (CompoundExpressionImpl)this.isTrue(y);
        }else{
            yp = (CompoundExpressionImpl)y;
        }
        
        //TEST FIX
        //TODO Eclipselink Bug 316144
//        if (yp.isPredicate() && yp.expressions.isEmpty()){
//            if (yp.isNegated()){
//                return yp;
//            }else{
//                return xp;
//            }
//        }
//        if (xp.isPredicate() && xp.expressions.isEmpty()){
//            if (xp.isNegated()){
//                return xp;
//            }else{
//                return yp;
//            }
//        }
        org.eclipse.persistence.expressions.Expression currentNode = xp.getCurrentNode().and(yp.getCurrentNode());
        xp.setParentNode(currentNode);
        yp.setParentNode(currentNode);
        return new PredicateImpl(this.metamodel, currentNode, buildList(xp,yp), BooleanOperator.AND);
    }

It's working in my simple tests.
Do you agree with this fix ?
Comment 7 Tom Ware CLA 2010-09-03 14:53:11 EDT
I took a look at your suggested fix.  There is a usecase that will break with that fix.  That case is an expression like this:

            cq.where(qb.and(qb.disjunction(), qb.conjunction()));

In this case qb.disjunction() and qb.conjunction() are used to represent false and true.  The code you have commented out is used to handle that case.
Comment 8 Gergely Barna CLA 2010-10-28 18:41:23 EDT
Is there a chance to get this bug fixed in 2.1.2?
Comment 9 Mikael Nousiainen CLA 2010-10-29 02:53:43 EDT
I hope that too. I just wonder that you don't consider this bug as a critical bug, because it prevents certain _very simple_ kind of queries from executed correctly. I bet a lot of people are using IS (NOT) NULL with AND. Or does someone know a workaround for this?
Comment 10 Vitor Souza CLA 2010-10-29 03:00:57 EDT
(In reply to comment #9)
> I hope that too. I just wonder that you don't consider this bug as a critical
> bug, because it prevents certain _very simple_ kind of queries from executed
> correctly. I bet a lot of people are using IS (NOT) NULL with AND. Or does
> someone know a workaround for this?

On the system I was developing when I ran into this bug the workaround was to use JPQL for that specific query. With JPQL it works fine for me.

The first comment also mentions the "less-readable" notEqual() or equal() as a possible workaround too.

Vítor Souza
Comment 11 Tom Ware CLA 2010-11-01 10:14:23 EDT
2.1.2 is closed to check-ins as it will ship soon.

With the current number of votes I would consider this bug a possibility, but not a guarantee for the next release.

Community: Please continue to vote for this bug if you consider it important.
Comment 12 pj.chartre CLA 2010-11-02 03:55:08 EDT
Add my vote !
This case is used in simple requests.  This fix is very important for industrial
Comment 13 Tom Ware CLA 2010-11-04 10:25:15 EDT
Targetting for 2.2.0 and taking ownership.

2.2.0 is current scheduled to be the first release after 2.1.2
Comment 14 Tom Ware CLA 2010-11-04 10:28:24 EDT
Created attachment 182372 [details]
Propsed fix
Comment 15 Tom Ware CLA 2010-11-04 11:37:53 EDT
Created attachment 182384 [details]
Updated Patch
Comment 16 Tom Ware CLA 2010-11-04 11:40:11 EDT
Created attachment 182386 [details]
Updated Patch
Comment 17 Tom Ware CLA 2010-11-04 11:43:28 EDT
Created attachment 182388 [details]
Updated Patch
Comment 18 Tom Ware CLA 2010-11-04 11:59:56 EDT
Fixed the checks for disjunction and conjunction to check for a null CurrentNode intstead of empty expressions

Reviewed by Chris Delahunt

Added tests to JUnitCriteriaUnitTestSuite for AND and OR

Tested with JPA LRG
Comment 19 Eclipse Webmaster CLA 2022-06-09 10:22:45 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink