General JPA query question

Hello world,
I'm new to JPA 2.0 and there are few things I don't understand.
BTW: I can't figure out the keywords to search for this question, so please pardon me if it's one of the most asked.
Using the Preview, I've seen that alignment went straight to Hell, so I tried to make this as readable as I could using pipes in place of white spaces in the result sets.
I have a couple of tables:
CUST table (for customers):
CUST_ID (pk, integer)
CUST_NAME (varchar)
ORD table (for orders):
ORD_ID (pk, integer)
ORD_STATUS (char) can be: N for new, S for shipped, D for delivered
CUST_ID (fk, integer)
The relationship is, of course, a "one to many" (every customer can place many orders).
Content of the tables:
CUST_ID|CUST_NAME
1|elcaro
2|tfosorcim
3|elppa
ORD_ID|ORD_STATUS|CUST_ID
2|N|1
3|N|1
4|N|1
5|S|1
6|S|1
7|D|1
8|D|1
9|D|1
10|D|2
11|N|2
12|S|3
13|S|3
Here's how I annotated my classes:
Customer.java:
@Entity(name = "Customer")
@Table(name = "CUST")
public class Customer implements Serializable
private static final long serialVersionUID = 1L;
@Id
@Column(name = "CUST_ID")
private Integer id;
@Column(name = "CUST_NAME")
private String name;
@OneToMany(mappedBy = "customer")
private List<Order> orders;
// Default constructor, getters and setters (no annotations on these)
Order.java:
@Entity(name = "Order")
@Table(name = "ORD")
public class Order implements Serializable
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ORD_ID")
private Integer id;
@Column(name = "ORD_STATUS")
private Character status;
@ManyToOne
@JoinColumns
@JoinColumn(name = "CUST_ID", referencedColumnName = "CUST_ID")
private Customer customer;
// Default constructor, getters and setters (no annotations on these)
Everything works just fine, the following JPQL query yields the results I expected:
select c from Customer c
it returns three objects of type Customer, each of which contains the orders that belong to that customer.
But now, I want to extract the list of customers that have orders in status 'N', along with the associated orders (only the status 'N' orders, of course).
Back in the good ol' days I would have written an SQL query like this:
select c.cust_id, c.cust_name, o.ord_id, o.ord_status
from cust c
inner join ord o on (o.cust_id = c.cust_id)
where o.ord_status = 'N'
and it would have returned the following result set:
CUST_ID|CUST_NAME|ORD_ID|ORD_STATUS
1|elcaro|2|N
1|elcaro|3|N
1|elcaro|4|N
2|tfosorcim|11|N
The following JPQL query, however, doesn't yield the expected results:
select distinct c from Customer c join c.orders o where o.status = 'N'
it returns the correct set of customers (customer 'elppa' doesn't have any status 'N' order and is correctly excluded), but each customer contains the full set of orders, regardless of the status.
It seems that the 'where' clause is only evaluated to determine which set of customers has to be extracted and then the persistence provider starts to navigate the relationship to extract the full set of orders.
Thinking a little about it, I must admit that it makes sense.
I then tried out another JPQL query:
select c, o from Customer c join c.orders o where o.status = 'N'
this JPA query yields results that are similar to the ones produced by the previous SQL query: each result (4 results as expected) is a 2-object array, the first object is of type Customer and the second object is of type Order. But, again, the objects of type Customer contain the full set of related orders (as I expected, this time). Not to mention the fact that now the orders are not contained in the Customer objects, but are returned separately, just as in an SQL result set.
Now the question is:
Is it possible to write a JPA query that filters out, not only the customers that don't have an order in status 'N', but the related orders (fetched during relationship navigation) that are not in status 'N' as well?
What I'd like to be able to get is a 2-customer result where each customer contains only its status 'N' orders.
I read the Java EE 6 Tutorial and one of the examples (the Order Application) has a schema that is similar to mine, but I couldn't find a query like this (in the downloaded source code).
Although I think the above is standard behavior, I use an Oracle Weblogic 12c server (through its Eclipse adapter) and the persistence provider appears to be EclipseLink.
Thanks in advance.
Best regards,
Stefano
Edited by: user11265230 on 17-apr-2012 14.11

Hello,
When returning an entity from JPQL, it gives you the entity as it is in the database. Your "select distinct c from Customer c join c.orders o where o.status = 'N'" is asking for all customers that have an order with a status of 'N', so that is what it gives you. There is no condition to filter anything on the relationship when building the Customer object in JPA - doing so would mean returning a managed entity that does not reflect what is in the database. This would affect other queries, since JPA requires that queries return the same instance of an entity regardless of the query that is used to bring it back. So a query using your "where o.status = 'N'" would cause conflicting results when used with a query using "where o.status = 'Y'". And these queries would make the EntityManager unable to determine what has changed on the returned objects.
EclipseLink does have the ability to filter over relationships, it is just not available through standard JPA and I would strongly discourage it. Instead of querying for Customers, why not change the query to get Orders instead -
"select o from Customer c join c.orders o where o.status = 'N'". Assuming Orders have a ManyToOne back reference to their Customer, this will mean you do not need to travers the Customer-> order relationship. If using
"select c, o from Customer c join c.orders o where o.status = 'N'"
I am not sure why you would use the orders from the returned customers instead of the orders returned in the results though.
You could also return "select c.id, c.name, o.id, o.status from Customer c join c.orders o where o.status = 'N'" which is the equivalent of what you would get from the SQL you initially posted.
Regards,
Chris

Similar Messages

  • JPA query language syntax

    My question is if JPA query language syntax allows full qualified class names in the SELECT clause of the query, e.g.:
    SELECT * FROM com.abc.Person
    This works well with Hibernate, but TopLink Essentials complains about the dots in com.abc.Person.
    In the Java EE 5 Tutorial only partially qualified names ( SELECT * FROM Person) are used.
    There are only examples with fully qualified names for constants in WHERE clauses.

    my first guess:
    SELECT t FROM tablename t WHERE t.timestamp>:somethingwhere :something
    is handled with something like: (..).setParameter("something", someSQLDate);

  • General Leger query to include  document  remarks(254 char)

    Hi,
    Customer wants to include AR(Inv & CM), AP(Inv & CM), Incoming payment & Outgoing Payment document remark into General Ledger query beside standard journal remarks.
    How to derive the query to link journal entry with original journal document remark?
    Regards
    Thomas

    Hi Gordon,
    I am asking for 2 customers.
    First customer had volume of transactions being posted. They are in retail industry.  Can FMS be made to update all the history journals automatically?
    Second customer is still in implementation stage so it is still possible to create UDF and FMS on each transaction but if it can made automatically, the better. I scared user forgot to drill back journal remark from source document to run FMS.
    Thanks

  • How to configure lazy/eager loading for each JPA query

    Hi!
    I have extensive EJB model (entities with many child entities, entities with association to other large (many fields, BLOBs including) entities, and so on) and I would like for each JPA query configure what properties or associated entities (actually - in arbitrary depth) of selected entities should be fetched.
    E.g. for one query I would like to fetch only Order (and no data of associated entities), but for other queries I would like to fetch Order, Order.Customer, Order.ShippingAddress.ZipCode and nothing else ( e.g. if there is Ordere.Route, Order.Billing and other associations, then I would like not to waste resources for fetching them). In both case the select clause of query can include only Order, but the results should be different - i.e. - there is no associated data in the first case and there are some associated data the second case.
    I know that one solution is to declare all associations as lazy and then - after reading the result of query - do some touching for retrieving the associated data:
    String check = order.Customer.toString();
    check = order.ShippingAddess.ZipCode.toString();
    But I see 2 problems with this: 1) it is not nice (resources are wasted for simply touching associated entities); 2) I assume that each "touch" operation generates other query to database that could be executed together with the original query. So - it would be nice to configure JPA query somehow to let it know which associations will be required from the result and which not.
    What is the best practice?
    I found, that JBoss server has lazy-loading-group configuration, but - I guess - it is JBoss specific:
    http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/4.2/html/Server_Configuration_Guide/Loading_Process-Lazy_loading_Process.html
    besides - it is XML and it would be more pretty if query configuration could be done with annotations!

    JPQL has a "fetch" construct in which you can force a lazy element to be fetched using a query - I must note that I have had unexpected results with it in the past but that was using an old version of Hibernate and I wasn't very experienced with JPA yet.
    http://docs.oracle.com/cd/E15051_01/wls/docs103/kodo/full/html/ejb3_langref.html#ejb3_langref_fetch_joins

  • JPA Query set parameter list of objects

    Hi Experts,
    Currently i am looking for the resolution to the the following JPA Query. I am sure you guys already came across the answer for that. Please help me to spot some light.
    Assume a relation Employees --> Departments. I have list of department and i would like to get all the employees belong to the departments. I was trying using the following JPA query
    Select o from EmployeeEntity where o.deparment IN ( :departments ) then set the parameter value to the List of department objects. Now i am getting the following exception
    at org.eclipse.persistence.exceptions.QueryException.invalidOperatorForObjectComparison(QueryException.java:598)
         at org.eclipse.persistence.internal.expressions.RelationExpression.normalize(RelationExpression.java:388)
         at org.eclipse.persistence.internal.expressions.CompoundExpression.normalize(CompoundExpression.java:218)
    Any hit ?
    Thanks

    Hi,
    You can try the following query
    select e from Employees e where e.Departments.departmentid in (:deptno)
    then set the parameter value to the List of departmentid
    Thanks

  • Convert JPA Query getResultList to Array

    I have been struggling with this problem for several hours now. All I have succeeded in doing is attempt every possible way to convert a List into an array and I just get errors.
         // create native SQL query
         Query q = em.createNativeQuery("SELECT * FROM Project p");
         // get and process the results
         List<Project> list = q.getResultList();
            Project[] retVal = new Project[list.size()];
         for (int i = 0; i < list.size(); i++)
             retVal[i] = list.get(i);
         }One would assume this to work, however this generates a ClassCastException, cannot convert Object to Project, oddly because as far as I can see everything in the code is strongly typed. I think Persistence fills the typed List with Object and not Project??
    So I tried:
    Project[] retVal = list.toArray(new Project[0]);This generates an ArrayStoreException.
    Finally I tried the basic, should generate x-lint warning:
    Project[] retVal = (Project[])(list.toArray());This also return ClassCastException, same reason as the first attempt.
    I want my WebService function to return a standard Project[] not the java.lang.List class. But it seems JPA queries only support getting a List. I have googled to no end for a solution. Help appreciated!
    Thanks.

    You are almost right, you can solve this two ways as below:
    First, use native query with result class reference.
    Second, use JPA query with createQuery method.
    Both the options should work, see code below:
    // First option, create native SQL query with result class reference.
    Query q = em.createNativeQuery("SELECT * FROM Project p",Project.class);
    // Second option, Create JPA Query.
    // Query q = em.createQuery("SELECT p FROM Project p");
    // get and process the results
    List<Project> list = q.getResultList();
    // Putting result to an array
    Project[] retVal = new Project[list.size()];
    list.toArray(retVal);*Cheers,
    typurohit* (Tejas Purohit)

  • Simple JPA - JSF question

    Welcome!
    I Have simple question regarding updating JPA entities from JSF application
    One option is to directly invoke entity manager code from JSF managed bean action, but in this case we must explicitly deal with transactions (and we don't get other EJB benefits).
    Other approach is to create EJB as a stateless session bean. And delegate all the operations on entities to the EJB. In this case container create transactions for us.
    Please correct me if I wrongly understand this topic.
    My key question is how to update entity bean, which I have persiteted earlier. I assume it's illegal to issue manager .find method in EJB class, return managed entity as an object to JSF backing been and then modify it. Normally entity bean should be managed, but in this case there is no transaction support in JSF backing bean and hence we cannot modify the object directly.
    I assume that correct way is to detach entity in EJB, pass this object to JSF backing bean. In this case entity will not be managed, then edit it in JSF and finally update in EJB by .merge method.
    I assume multi-user environment (currently I am using glassfish if it does matters)
    Best regards
    Pawel

    Thanks for responding r035198x (this place has some memorable usernames :) ).
    You were absolutely right about flagging me up for not catching the exception (at the time I didn't know how to handle exceptions as im still learning). I am now using:
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Error deleting record: "+ex.getMessage()));and am now getting the following when pressing the delete button:
    Error deleting record: Internal Exception: java.sql.SQLIntegrityConstraintViolationException: DELETE on table 'MBUSER' caused a violation of foreign key constraint 'USERPOST_OWNER_ID' for key (4). The statement has been rolled back. Error Code: -1 Call: DELETE FROM MBUSER WHERE (ID = ?) bind => [4] Query: DeleteAllQuery(name="messageboard.entity.MBUser.deleteUser" referenceClass=MBUser sql="DELETE FROM MBUSER WHERE (ID = ?)")
    This is probably getting out of the realm of JSF, but in case your interested I can delete a user which does not have any child posts or threads (this is a messageboard), but if that user owns any threads or posts then it shows the above error. At this stage I am guessing its because I am not deleting joined child objects which are in persistence, and therefore will not allow the parent to be deleted without first the children being deleted. I was hoping that the cascade tag in the @OneToMany annotation would do it for me, but that doesn't seem to be the case:
        @OneToMany(mappedBy = "owner", cascade = CascadeType.ALL)
        private List<UserPost> ownedPosts = null;
        @OneToMany(mappedBy = "owner", cascade = CascadeType.ALL)
        private List<UserThread> ownedThreads = null;Therefore I guess i'll have to construct a NamedQuery a bit more complicated than the current one im using. Still, at least im making progress :) Thanks...

  • General Airport Extreme questions

    I have some general questions regarding the dual band technology and how it relates to my specific setup. A bit of background:
    I have 20Mbps cable internet and I am running the new Airport Extreme on a pc running XP to broadcast my wireless signal. I have an iPhone 3GS, iPhone 4 and iPad. I also have an Airport Express that I use in bridge mode so that I can connect my PS3 in a wired fashion.
    My questions:
    -How do wireless networks work when you have both "g" and "n" devices? (which I do)
    Does the router send out simultaneously a 2.4 and 5.0 signal for each capable device to pick up? Do the g devices pick up the 2.4 signal while the n devices pick up the 5.0? Or do all devices pick up the 2.4 signal since there are non "n" rated devices on the network? I have read many conflicting ideas on this.
    - I have spoken with multiple Apple customer service people and have gotten differing advice on how to improve my devices' connectivity to the network as I have been experiencing unacceptable levels of interference on all devices.
    One rep reccomended that in the Airport Utilities, under wireless options that I check the 5GHz box to setup a seperate 5GHZ network for the n devices. Another rep dismissed this idea.
    Does creating this new 5.0 network keep the network signal from being bumped down to "g" speeds when "g" rated devices are connected?
    How am I to better off setting my networks up so that my n devices as well as my g devices get the best performance and connectivity?
    -I use an Airport Express in bridge mode with my PS3 and it seems to be helping my connections speeds. When I was connected wirelessly, the speeds would either be non-existent or unacceptable. I know the PS3 has a "g" antenna. I have the airport express connected to the 5.0ghz wireless network in Airport Utilities. Am I actally now connecting to the 5.0ghz signal and converting to the PS3 at higher bandwidth then I would be otherwise if I was connected to the 2.4ghz wireless signal?
    I appologize for the longwinded post.
    Any insight I will be most appreciated as I am banging my head against the wall here.
    Scott

    The default setup for the AirPort Extreme provides a dual band wireless network with a Radio Mode that looks like this:
    802.11a/n --- 802.11n/g/b
    The 5 GHz band is on the left and the 2.4 GHz is on the right of the --- dashes
    Also as a default, the same wireless network name is used for both bands. The theory here is that any device will automatically connect to the best signal quality. This works great for older "g" devices because they can only connect to the 2.4 GHz band, so you know where they will be at all times. You never need to be concerned about a "g" device slowing down a faster "n" device on the 5 GHz band because the "g" device cannot even connect to the 5 GHz band.
    But note that newer "n" devices can connect to either the 5 GHz band or the 2.4 GHz band. So, it's possible that you may have a "n" device and a "g" device on the 2.4 GHz band and the "n" connection will slow a bit if the "g" device is really active.
    It gets a bit more complicated if you have a new iPhone, which can connect at "n" speeds, but only to the 2.4 GHz band. The new iPad can connect to either 2.4 GHz or 5 GHz.
    Most users are better off if they leave the settings as recommended on the AirPort Extreme. That's because each device will connect to the band with the best available signal quality. Isn't that what you really want?
    If you will concentrate on signal quality, which is a combination of signal strength and low noise, you'll be fine.
    Most problems arise when users think that they want to connect to the 5 GHz band because the speeds can be faster there. So, they assign a separate name to the 5 GHz network and then "point" their computer at that band. The potential issue with doing this is that 5 GHz signals are much weaker than 2.4 GHz signals.
    So, if the computer is several rooms away and you have "forced" it to connect to 5 GHz, you are likely telling it to connect to a signal that is both +weaker and slower+ than the 2.4 GHz signal at that location. The signal always slows down as it moves further from the router or encounters obstructions.
    As I said, most users will do well to use the default settings and let each device find the best connection automatically. With a mix of a number of devices, you'll never be able to find the single "perfect" setting. With wireless, there are always compromises. No way to avoid that, I'm afraid.

  • Simple Query Question - How do I return the Last 3 records of a Table?

    Question.
    For example, I have a table that has 50 records.
    How do I, specify in SQL to only return the last 3 records of the table.
    Select a.* from table a where ????

    I was just trying to show an example to a friend on
    how something like this would work and if it was even possible. But it won't work. Here's a simple example:
    SQL> create table emp
      2  (id)
      3  as
      4  select object_id
      5  from   all_objects
      6  order  by object_id;
    Table created.
    SQL> select *
      2  from  (select rownum rn
      3               ,b.*
      4         from   emp b)
      5  where  rn > ( select (max(rownum) - 3)
      6                from    emp)
      7  ;
            RN         ID
         40830      55891
         40831      55892
         40832      55893So far, so good. These are the "last 3" rows inserted. Now delete a bunch of rows and insert 3 new ones:
    SQL> delete emp where id < 40000;
    33423 rows deleted.
    SQL> commit;
    Commit complete.
    SQL> insert into emp values (60000);
    1 row created.
    SQL> insert into emp values (60001);
    1 row created.
    SQL> insert into emp values (60002);
    1 row created.
    SQL> commit;
    Commit complete.
    SQL> select *
      2  from  (select rownum rn
      3               ,b.*
      4         from   emp b)
      5  where  rn > ( select (max(rownum) - 3)
      6                from    emp)
      7  ;
            RN         ID
          7410      55891
          7411      55892
          7412      55893Here's the problem. Even though the "last 3 rows" are 60000 - 60002, I still get the same ones as the first query.

  • JPA query by entity/object ?

    I am trying to write an abstract API which dynamically assigns any Entity Class that needs to be persisted and retrieved using the Entity Manager.
    Saving into the database is not a problem, I just do entityManager.save(Class) and it works for any class that needs to be persisted.
    However, when querying for the object based upon the attributes, I want to avoid naming particular attributes and want to use the Entity class's attributes against itself for querying.
    For example, the client program will say something like this to query by name and age of a Person:
    -------calling (client) program: ---
    Person p = << get from UI, not saved yet, no Id but has all other attributes like name and age etc. >>
    List<Person> persons = dao.getAllThatMatch(p);
    --- end client Program --
    --- DAO class ---
    List<T> getAllThatMatch(T t) {  //note that expectation is that returned is a list of Object which is the same as the querying object
    List<T> entityList = em.someFinderMethod(t);
    //the someFinderMethod method should automatically query for all Person objects that match the attributes provided by the object of Person supplied as criteria
    //NOTE: there is no attribute mentioned extensively like name, age etc.
    return entityList ;
    -- end DAO class --
    Edited by: user7626479 on Feb 6, 2013 3:55 PM
    Edited by: user7626479 on Feb 6, 2013 3:55 PM

    Query by example is not included in the JPA standard, but it is possible to do with EclipseLink.
    See http://wiki.eclipse.org/EclipseLink/Examples/JPA/ORMQueries#Query_By_Example
    for how to use query by example with native EclipseLink queries. To execute a native query through JPA, you will need to call createQuery(DatabaseQuery query) on the org.eclipse.persistence.jpa;JpaEntityManager obtained from the javax.persistence.EntityManager instance by calling getDelegate() or unwrap.
    Best Regards,
    Chris

  • What to be targetted by JPA query?

    In JPA the SELECT query is against entity objects, but the UPDATE against DB records, aren't they?
    i coded some basic JPA staff, then found that the getResultList() method to SELECT query always returned the latest states of entity objects but not of DB records, in contrast the executeUpdate() method to UPDATE query always changed the values of DB records but not of entity objects.
    Unfortunately i couldn't prove it from JPA Spec directly. What are the reasons behind? Pls correct me if i were wrong. Thx!
    Edited by: solfan on Jun 24, 2009 3:26 AM

    I suggest you first study and understand fully what the relation between a "transaction", an "entity manager" and a "managed entity" is, before you make any further assumptions.

  • JPA Query.setFirstResult(int) ... What if the table has much more entries

    Hello.
    I want to page my query results but I have a table that has a long primary key. As I see Querry.setFirstResult() can only take an int as a parameter.
    How can I page my results if I have much more than 2,147,483,647 entries? I could implement it by myself... but isn't there some standard way?

    gimbal2 wrote:
    I'd say in theory it is not possible to do that with JPA (or the underlying ORM implementations). Luckily in practice there is no need for such functionality. Who is going to paginate more than 2 billion results?I find it very plausible. Say you have a table that might grow very large ... with A LOT of entries ( more than 2 bilion ) and you want to be able to browse all of them in a client GUI.

  • Oracle 10g and parallel query question

    Hi Oracle on SAP Gurus!
    We are currently thinking of activating parallel query for certain segments (large application tables and indexes). We searched in SAPNet and SDN and have also studied the SAP Note 651060. But we did not find a complete answer to the following question which is very important for us:
    Which kinds of queries (despite from full table scan and index scan in partitioned indexes) support parallel queries and which ones do not support parallel queries?
    This is important for us to find out whether we have candidates for parallel queries or not.
    Thanx for any hint!
    Regards,
    Volker

    But why do you not propose to use parallel query in OLTP systems?
    If the queries are accessed very frequently you will just run out of cpu and io ressources. OLTP systems are (historical) typically multi user systems. You can off course use PQ for 'single user' activities, like index rebuilds, some batchjobs, but you shouldn't do for frequent user queries.
    If you have time look at this interesting Article [Suck It Dry - Tuning Parallel Execution|http://doug.burns.tripod.com/px.html]
    It is quite old, and you don't have to read all tech details, but i recommend having a look at the conclusions at the end.
    May it make sense to use partitioning of these tables in conjunction with parallel query?
    I know some guys, who do partitioning on OLTP systems, even SAP systems. But they don't use PQ then. The use partitioning to work on a smaller set of data. In your case the range scans, would need to scan only one partition, saving buffer cache and effectively speeding up execution. So you don't need PQ to scan all partitions at all, this would be a typical OLAP approach.
    Best regards
    Michael

  • Coherence+JPA query issues

    Hello everyone,
    I've setup Coherence 3.6 to use JPA according to the generic instructions found here [http://coherence.oracle.com/display/COH35UG/Configuring+Coherence+for+JPA]
    This works fine and I can actually get data out of the DB backed cache. What I've found however is that CohSQL queries do not return anything unless the entry is already in Coherence. I'm using this piece of code to test query Coherence
    public <T> List<T> getAll(Class<T> type) {
            final List<T> data = new ArrayList<T>();
            Filter filter = QueryHelper.createFilter("value().class=?1", new Object[] { type });
            Set<Map.Entry<?, T>> filteredSet = cache.entrySet(filter);
            for (Map.Entry<?, T> t : filteredSet) {
                data.add(t.getValue());
            return Collections.unmodifiableList(data);
      }Should I be expecting Coherence to query the DB at this point, or is CohSQL confined to whatever's already in the cache?
    Thanks
    Edited by: 876420 on 01-Aug-2011 07:07

    Section 20 of the dev guide:
    "It should be noted that queries apply only to currently cached data (and will not use the CacheLoader interface to retrieve additional data that may satisfy the query). Thus, the data set should be loaded entirely into cache before queries are performed. In cases where the data set is too large to fit into available memory, it may be possible to restrict the cache contents along a specific dimension (for example, "date") and manually switch between cache queries and database queries based on the structure of the query. For maintainability, this is usually best implemented inside a cache-aware data access object (DAO)."
    Cheers,
    Steve

  • Left Join Query Question

    Version 10.2.0.4.0
    I have a question on the expected behavior of the query below.
    When I run the query below with the constraint on t1.partid = 789,  I get the query result t2.Indicator showing "SPECIAL" as expected.
    However, if I remove the constraint, and return all orders and parts, for the "789" part, the Indicator column is null.
    select t1.orderid, t1.partid, t2.Indicator
    from Orders a left outer join
    select partid, 'SPECIAL' as Indicator
    from vendors
    where vendorname like '%ABC%'
    ) t2
    on t1.partid = t2.partid
    where t1.partid = '789'
    I can address the issue with a case statement (below) or likely restructuring into a better statement. 
    But I'm just curious if this is expected or if there is some SQL rule being violated in the first example.
    I tried to search for this to see if it was already addressed but didn't have much luck.
    This works:
    select t1.orderid, t1.partid,
    case when t1.partid is not null then "SPECIAL" else null end as Indicator
    from Orders a left outer join
    select partid, 'SPECIAL' as Indicator
    from vendors
    where vendorname like '%ABC%'
    ) t2
    on t1.partid = t2.partid

    Sorry, it's been a while since I posted and should have read the rules.  And I didn't properly reference the alias.  So Post #1 was bad. 
    When I mockup a small set of data (shown below), I don't get the error.  The original query actually joins to a few other (seemingly) irrelevant tables and I tried to simplify it here  So I guess if I can't replicate it, then there might not be much assistance that can be provided.
    This was more of a curiousity than anything else to see if perhaps someone came across this before.
    For what it's worth:
    create table t1 (orderid number,
                 partid varchar2(20)
    create table t2
            (vendorid varchar2(20),
             partid varchar2(20)
    insert into t1 values(1, '123');
    insert into t1 values(2, '456');
    insert into t1 values(3, '789');
    insert into t2 values ('ABC','789');
    insert into t2 values ('DEF','123');
    insert into t2 values ('EFG','456');
    insert into t2 values ('ABC','7891');
    insert into t2 values ('DEF','1231');
    insert into t2 values ('EFG','4561');
    select t1.orderid, t1.partid, t2.Indicator
    from t1 left outer join
    select partid, 'SPECIAL' as Indicator
    from t2
    where vendorid like '%ABC%'
    ) t2
    on t1.partid = t2.partid
    the query that gives unexpected behavior is (although I can't replicate on this simplified version):
    select t1.orderid, t1.partid, t2.Indicator
    from t1 left outer join
    select partid, 'SPECIAL' as Indicator
    from t2
    where vendorid like '%ABC%'
    ) t2
    on t1.partid = t2.partid

Maybe you are looking for