Whoops.
Sorry for not finishing #2. However “how I get the Company” is also
addressed by #4
public
void deleteEmployeeWithId(Long id) {
Employee e4 = entityManager.find(Employee.class, id);
List<Employee>
employeesInCompany =
e4.getCompany().getEmployees();
//
Iterate over the employeesInCompany to find e4 and then remove it from
the collection
A) is find used for company as well?
As
explained in the above fragment, I get E4 and ask it for its owning
company. That is the Company I need.
Then
I look in the collection of Employees referenced by the Company…etc…etc.
B) Is E4 looked up using the em.find api
successfully? If so, does em.refresh(company) work to show it in the
collection?
E4
is found successfully by em.find API.
Just
tried your suggestion to em.refresh(company). Bingo!!
That
fixed the problem!
Relieved
as I am to get resolution….and ever so thankful….I am curious, though.
Why do I have to do this step? After all, E4 – when it was first
created – was injected into the collection owned by the Company. So
isn’t it already in the (Eclipselink) session?
Sri
Hello,
#2 shows you looking up an Employee, not the company.
A) is find used for company as well?
B) Is E4 looked up using the em.find api successfully? If so, does
em.refresh(company) work to show it in the collection?
Regards,
Chris
On 29/07/2011 4:03 PM, Sri Sankaran wrote:
Here
are my answers to your questions:
1) I assume step 5 is a merge, so how are you
holding onto E4 and does it have a primary key assigned after the
transaction completes?
Yes
step 5 is a merge. E4 is in a collection managed by the Company.
public
class Company {
private List<Employee> employees;
…
}
2) How is the company obtained in the second transaction so that you
can look up E4?
The
client conveys to the server the E4’s ID (primary key).
The
server uses that to do a entityManager.find(Employee.class, id_for_e4);
3) What is in the collection?
The
employee entities. Or did I take your question too literally? Since
using the debugger+break points did not help I resorted to the age old
technique of insert-a-print-statement. I listed the contents of the
company.getEmployees() collection just before the failed deletion of
E4. It only had E1 & E2.
4) How are you looking up E4 in the collection?
public
void deleteEmployeeWithId(Long id) {
Employee e4 = entityManager.find(Employee.class, id);
List<Employee>
employeesInCompany = e4.getCompany().getEmployees();
//
Iterate over the employeesInCompany to find e4 and then remove it from
the collection.
Sri
So steps 1-5 are one transaction context, and
then are repeated in a second transaction.
Questions:
1) I assume step 5 is a merge, so how are you holding onto E4 and does
it have a primary key assigned after the transaction completes?
2) How is the company obtained in the second transaction so that you
can look up E4?
3) What is in the collection?
4) How are you looking up E4 in the collection?
Regards,
Chris
On 29/07/2011 3:08 PM, Sri Sankaran wrote:
I
do not understand what you are referring to by “first transaction”.
Here’s a little more detail on the implementation:
Precondition:
Company has 3 Employees E1, E2, E3
User
issues “delete E3” and “add E4” request
The
server logic is implemented thusly:
Find
Employee E3 in Company’s collection of Employees
Remove
E3 from the collection – A pure Java operation, i.e. no
dao.delete(employee)
dao.flush()
– to ensure that the delete operation is executed. This is to work
around Eclipselink’s desire to perform inserts first (It is a longer
sidebar to explain why we don’t want that to happen)
Add
E4 to the Company’s collection of Employees
Save
the Company to the database
Steps
1-5 are all a part of the same transaction.
The
same steps repeat when user subsequently asks to delete E4 and add E5.
It fails at step 2 saying that E4 does not exist.
Sri
Does the second step wait for the first
transaction to commit before reading in the company? If not, you many
need to refresh the company after the transaction is fully committed to
see the changes as they are not visible to other contexts until the
commit occurs.
If this isn't the issue, can you describe the api you are using in each
step?
Best Regards,
Chris
On 29/07/2011 12:41 PM, Sri Sankaran wrote:
Eclipselink
version: 2.0.0
Consider
the following simplification of my actual business case:
A
Company entity has a collection of Employee entities
@Cache(shared
= true, expiry = 900000)
@Table(name
= "COMPANIES ")
@OneToMany(mappedBy = "company", fetch = FetchType.EAGER, cascade =
CascadeType.ALL)
public List<Employee> getEmployees() {
@Cache(shared
= true, expiry = 900000)
@Table(name
= "EMPLOYEES ")
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "COMPANY_ID", nullable = false)
Consider
the case where a Company has 3 Employees (E1, E2 & E3).
The
user of the application (using the user interface) deletes E3 &
adds E4. The logic works correctly and E3 is removed from the database
and an E4 is inserted.
Next,
the user deletes E4 and adds E5. Now when application attempts to
perform this operation, I am told that the employees collection that is
owned by the Company object does not contain an E4!!
How
come? Recall that in the previous step the insert happened correctly.
Equally puzzling – not to mention aggravating – is that if slowly step
through the logic in a debugger I do not see any error.
I
should also mention an ominous warning I see when I build the
application:
could
not be weaved for change tracking as it is not supported by its
mappings.
I have
not figured its cause and I don’t know if this has any bearing on my
current problem.
_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users
_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users
_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users