Entity Framework Can't Load Related Entity - entity-framework

Ever since I started using POCO in my projects, I've been having problem querying data that references other entity on the query. The annoying part of it is that trying the same query on LINQPad works well.
For example, this esql query below:
SELECT VALUE TOP(1) a.AccountUrl FROM AppEntities.Accounts AS a WHERE EXISTS(SELECT VALUE u FROM a.Users AS u WHERE u.Username=#username)
throws the follow error when it tries to execute from my application.
Users' is not a member of type 'DelightModel.Account' in the currently loaded schemas. Near simple identifier, line 1, column 104.
I tried the same query on LINQPad with the same dll(Repository library) that my web application referenced, and it worked. Changing the query to return the full entity without projection (example below) also works with no problem.
SELECT VALUE TOP(1) a FROM AppEntities.Accounts AS a WHERE EXISTS(SELECT VALUE u FROM a.Users AS u WHERE u.Username=#username)
The above query work on my application.
Is this a bug or am I doing something wrong?
Please help point me towards the right direction. Thanks.

Related

Purpose of Eclipselink 2.6.0 query - SELECT ID FROM TBL WHERE ID=?

Has anyone got an idea why JPA Provider - Eclipselink (using version 2.6.0) generates query like:
SELECT ID FROM OPERATION WHERE (ID = ?);
or
SELECT ID FROM SUBSCRIPTION WHERE (ID = ?);
Why it needs to get ID providing an ID...
Maybe 1st or 2nd level Cache synchronization?
Maybe my queries are inaccurate...
In my queries I never ask directly this to execute - I use JPQL and never ask for ID giving some ID.
I have quite complex model and queries so I see no point in providing full code (or only if U really insist but I dont think it will help a lot).
Using Oracle 12c DB.
We have encountered the same issue with our Java application using EclipseLink 2.5.2. Specifically, we saw it whenever we inserted a new entity that had a M:1 relationship with another entity. A simplified use case would be:
A a = new A(); // the new entity
B b = lookupB(); // get existing entity from database
a.setB(b); // set M:1 relationship
em.persist(a); // save
In this case, we would always see a query for B (i.e., SELECT ID FROM B WHERE ID = #). After some research, we traced it down to the existence checking that EclipseLink performs before merging records.
We found that annotating the entity class for B with #ExistenceChecking(ExistenceType.ASSUME_EXISTENCE) prevented EclipseLink from running the query.
For a further discussion of this, see this related post.

Entity Framework 5 SaveChanges Not Working, No Error

None of the many questions on this topic seem to match my situation. I have a large data model. In certain cases, only a few of the fields need be displayed on the UI, so for those I replaced the LINQ to Entity query that pulls in everything with an Entity SQL query retrieving only the columns needed, using a Type constructor so that I got an entity returned and not a DbDataRecord, like this:
SELECT VALUE MyModelNameSpace.INCIDENT(incident.FieldA, incident.FieldB, ...) FROM ... AS ...
This works and displays the fields in the UI. And if I make a change, the change makes it back to the entity model when I tab out of the UI element. But when I do a SaveChanges, the changes do not get persisted to the database. No errors show up in the Log. Now if I very carefully replace the above query with an Entity Sql query that retrieves the entire entity, like this:
SELECT VALUE incident FROM MyDB.INCIDENTs AS incident...
Changes do get persisted in the database! So as a test, I created another query like the first that named every column in the entity, which should be the exact equivalent of the second Entity SQL query. Yet it did not persist changes to the database either.
I've tried setting the MergeOption on the returned result to PreserveChanges, to start tracking, like this:
incidents.MergeOption = MergeOption.PreserveChanges;
But that has no effect. But really, if retrieving the entire entity with Entity Sql persists changes, what logical purpose would there be for behaving differently when a subset of the fields are retrieved? I'm wondering if this is a bug?
Gert was correct, the problem was that the entity was not attached. Dank U wel, Gert! Ik was ervan verbluft!
I just wanted to add a little detail to show the full solution. Basically, the ObjectContext has an Attach method, so you'd think that would be it. However, when your Entity SQL select statement names columns, and you create the object using a Type as I did, the EntityKey is not created, and ObjectContext.Attach fails. After trying and failing to insert the EntityKey I created myself, I stumbled across ObjectSet.Attach, added in Entity Framework 4. Instead of failing, it creates the EntityKey if it is missing. Nice touch.
The code was (this can probably be done in fewer steps, but I know this works):
var QueryString = "SELECT VALUE RunTimeUIDesigner.INCIDENT (incident.INCIDENT_NBR,incident.LOCATION,etc"
ObjectQuery<INCIDENT> incidents = orbcadDB.CreateQuery<INCIDENT>(QueryString);
incidents.MergeOption = MergeOption.PreserveChanges;
List<INCIDENT> retrievedIncidents = incidents.ToList<INCIDENT>();
orbcadDB.INCIDENTs.Attach(retrievedIncidents[0]);
iNCIDENTsViewSource.Source = retrievedIncidents;

jpa lazy fetch entities over multiple levels with criteria api

I am using JPA2 with it's Criteria API to select my entities from the database. The implementation is OpenJPA on WebSphere Application Server. All my entities are modeled with Fetchtype=Lazy.
I select an entity with some criteria from the database and want to load all nested data from sub-tables at once.
If I have a datamodel where table A is joined oneToMany to table B, I can use a Fetch-clause in my criteria query:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<A> cq = cb.createQuery(A.class);
Root<A> root = cq.from(A.class);
Fetch<A,B> fetch = root.fetch(A_.elementsOfB, JoinType.LEFT);
This works fine. I get an element A and all of its elements of B are filled correctly.
Now table B has a oneToMany-relationship to table C and I want to load them too. So I add the following statement to my query:
Fetch<B,C> fetch2 = fetch.fetch(B_.elementsOfC, JoinType.LEFT);
But this wont do anything.
Does anybody know how to fetch multi level entities in one query?
It does not work with JPQL and there is no way to make it work in CriteriaQueries either. Specification limits fetched entities to the ones in that are referenced directly from the returned entity:
About fetch join with CriteriaQuery:
An association or attribute referenced by the fetch method must be
referenced from an entity or embeddable that is returned as the result
of the query.
About fetch join in JPQL:
The association referenced by the right side of the FETCH JOIN clause
must be an association or ele ment collection that is referenced from
an entity or embeddable that is returned as a result of the query.
Same limitation is also told in OpenJPA documentation.
For what is worth. I do this all the time and it works just fine.
Several points:
I'm using jpa 2.1, but I'm almost sure it used to work in jpa 2.0 as well.
I'm using the criteria api, and I know some things work diferent in jpql. So don't think it works some way or doesn't work because that's what happens in jpql. Most often they do behave in the same way, but not always.
(Also i'm using plain criteria api, no querydsl or anything. Sometimes it makes a difference)
My associations tend to be SINGULAR_ATTRIBUTE. So maybe that's the problem here. Try a test with the joins in reverse "c.fetch(b).fetch(a)" and see if that works. I know it's not the same, but just to see if it gives you any hint. I'm almost sure I have done it with onetomany left fetch joins too, though.
Yep. I just checked and found it: root.fetch("targets", LEFT).fetch("destinations", LEFT).fetch("internal", LEFT)
This has been working without problems for months, maybe more than a year.
I just run a test and it generates this query:
select -- all fields from all tables
...
from agreement a
left outer join target t on a.id = t.agreement_id
left outer join destination d on t.id = d.target_id
left outer join internal i on d.id = i.destination_id
And returns all rows with all associations with all fields.
Maybe the problem is a different thing. You just say "it wont do anyhting". I don't know if it throws an exception or what, but maybe it executes the query properly but doesn't return the rows you expect because of some conditions or something like that.
You could design a view in the DB joining tables b and c, create the entity and fetchit insted of the original entity.

Trying to traverse tables from sql database using entity framework targeting .net 3.5 websites

I'm simply trying to get data from two sql server db tables using ado.net entity framework. My code is:
using (Model.Entities e = new Model.Entities())
{
return e.PAGE.First().CONTROL;
}
The database is setup to have two tables, a control table which links to a page table via an 'id' field in the tables (control_id). There is one CONTROL object for each PAGE object.
I keep getting a null value for my return value and I know that's not right.
I can use vis studio and breakpoints to see that there is a PAGE object in 'e' and I can see that there are multiple CONTROL objects in 'e'. This isn't a large database, I just have some sample data in there to ensure that I get this working - so I know that there should be a CONTROL object connected to this PAGE (i've verified this through sql server).
I am very familiar with the general code syntax, I've been using LINQ for a couple of years; however, I have not done much work at all with the entity framework or ado.net 4.
It seems like if I just pull individual table data then it works fine (i.e. e.PAGE.First() .. or .. e.CONTROL.Where(x=>x.someValue.Equals('someValue') ) but if I try to pull by traversing through the tables then I get nothing back (NULL).
Hope that all makes sense.
Some questions for you:
I assume is a 1..1 between PAGE and CONTROL,
Is there a FK called "ControlID" on PAGE?
Do you have a navigational property called "Control" on your "Page" entity in your EDMX?
If the answer to all of the above is Yes, then this should work:
var page = e.Pages.Include("Control").First();
Here, you are returning the First "Page" record, and eager loading the associated control.
The SQL produced should be something like this:
SELECT p.*, c.*
FROM Page p
INNER JOIN Control c
on p.ControlId = c.ControlId

Doubt regarding JPA namedquery

I am trying to execute a namedquery
#NamedQuery(name="getEmployeeDetails",query="select e.username,e.email,e.image,e.firstname,e.lastname from Employee e where e.empid=?1")
Now when I execute this query in a EJB 3.0 Session Bean what is the object I should return.I tried returning Listits returning a Vector which creates a classcast exception.The employee table contains fields like password and other confidential details which I don't want to fetch.So I am not using select e from Employee e.
I am learning JPA can anyone help.
Below is the sample query which fetches only the required fields, but have to make such constructor for it.
Query : SELECT NEW package_name.Employee(e.username,e.email,e.image,e.firstname,e.lastname) FROM Employee e where e.empid=?1;
It will return Employee entity with selected fields & remaining will have default values.
Inspect the returned type by calling .getClass() on a returned object. I'd guess it's an array.
But this is not really a good way to use JPA. Select the whole entity and then just don't use what you don't need. It's not such a performance hit.