Heiko Kopp wrote: > > Hello Mike, > > thanks first for your fast answer on this. > > > Michael Dick wrote: >> >> Do you have CascadeType.REFRESH or CascadeType.ALL specified for >> Addresses? If a related entity no longer exists in the database then an >> EntityNotFoundException needs to be thrown (spec p. 75). >> > > Yes this is true, I added CascacdeType.REFRESH to the OneToMany() > Relationship for the addresses. To make sure that in case a Person is > refreshed, the list of addresses is refreshed too. However, I was not > aware that this might lead to an exception. >
With CascadeType.REFRESH we call refresh on the Person entity and its Address entities, if any of those don't exist in the database we have to throw an EntityNotFoundException (page 75 in the JPA 1.0 spec under the EntityNotFoundException paragraph). In this case it's correct behavior, but I can see how you might not have expected it. Heiko Kopp wrote: > > > Michael Dick wrote: >> >> It gets a little nebulous when you're talking about toMany relationships. >> EntityManager.refresh() indicates that the contents of the entity are >> updated from the database, but it looks like OpenJPA is refreshing the >> entity, and any related entities based on the references in memory. I'd >> say this is a bug, if you could open a >> https://issues.apache.org/jira/browse/OPENJPA JIRA issue we'll start >> working on the problem. Or if you don't have / don't want a JIRA account >> I can open it on your behalf. >> > To understand you correctly: The spec says that if a related entity no > longer exists in the database and the cascadeing type is set to REFRESH or > higher, an exception must be thrown. In this case, the system works > perfectly as it is and there is no bug. I was simply not aware that in > this situation a EntityNotFoundException might be thrown. > > However, if there should be no exception in case of CascadeType.REFRESH > set on the OneToMany relationship to the addresses and the refresh is > called uppon the Person, I should open a JIRA issue. > Sorry for the confusion. To put it more clearly if you're cascading this is a possible exception. If you aren't cascading then there's a different problem. I'll open a JIRA for the other problem if you aren't worried about it. Heiko Kopp wrote: > > > Michael Dick wrote: >> >> Your workaround seems safe for the time being. >> > Good, I will work with this for now. Let me add a question here. What is > from your pespective the correct way of making sure that every external > change of the database is reflected by the entity 'structure'? My thinking > here was to use refresh() and add the CascadeType REFRESH to all > relationships in the refreshed object. Now this might lead to the given > EntityNotFoundException. Fine, but how to handle this? As you said > yourself, my workaround is safe, but is it a good way of doing this? > > Thank you for your help, > > Heiko > I wish I had a more elegant solution to offer you. Something like this will also work : p = em.find(Person.class, 1); System.out.println(p); try { em.refresh(p); } catch (EntityNotFoundException enfe) { // If a related entity (Address) has been deleted in the database an EntityNotFoundException // will be thrown. // To recover try refreshing again (OpenJPA will not refresh the same missing row a second time). em.refresh(p); assertEquals(2, p.getAddresses().size()); } Whether this is better than calling em.find() is a matter of opinion. Hope this helps, -mike -- View this message in context: http://n2.nabble.com/EntityNotFoundException-caused-by-EntityManager-refresh-tp4901557p4913480.html Sent from the OpenJPA Users mailing list archive at Nabble.com.
