Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Lazy loaded relation after detach with cascade detach not detached.
icon5.gif  Lazy loaded relation after detach with cascade detach not detached. [message #1745853] Tue, 18 October 2016 12:24 Go to next message
Raffael Bachmann is currently offline Raffael BachmannFriend
Messages: 4
Registered: June 2013
Junior Member
Hi,

I'm not sure if this is a bug or correct behaviour. Imho it is wrong but I thought i ask here before filing a bug report.

Explanation:
Two entities Book and Page

@Entity
public class Book extends AbstractSimpleEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	@OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
	@OrderColumn(name = "position")
	@Getter
	@Setter
	protected List<Page> pages = new ArrayList<>();
}

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Page extends AbstractSimpleEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	@Getter
	@ManyToOne
	protected Book book;

	@Getter
	@Setter
	private boolean done = false;

	public Page(Book book) {
		this.book = book;
	}
}


And this function where the result is not what i expected
	private static void editFirstBookPage(Long bookId) {
		EntityManager em = EmfHandler.getEM();
		try {
			em.getTransaction().begin();
			Book book = em.find(Book.class, bookId);
			em.detach(book);
			List<Page> pages = new ArrayList<>(book.getPages());

			// Uncomment this to workaround the problem
			// for (Page page : pages) {
			// em.detach(page);
			// }

			pages.get(0).setDone(true);

			Book origBook = em.find(Book.class, bookId);
			em.refresh(origBook);
			origBook.setPages(pages); // thats where done flag is reseted
			// book = em.merge(book); //Same Problem with merge
			em.flush();
			em.getTransaction().commit();
			LOG.info("Updated Pages");
		} finally {
			if (em.getTransaction().isActive())
				em.getTransaction().rollback();
			EmfHandler.disposeEM(em);
		}
	}


Right after detaching the book entity I access the pages relation and because CascadeType.DETACH (CascadeType.ALL) I assumed, that the pages are also detached, but they are not. So setting pages on origBook refreshes the pages too because it is also CascadeType.REFRESH and so my done flag set back to false.
I can provide a maven project demonstrating this if someone is wants to test it.

What do you think? Is this a bug or correct behaviour?

Thanks
Raffael
Re: Lazy loaded relation after detach with cascade detach not detached. [message #1746305 is a reply to message #1745853] Wed, 26 October 2016 15:55 Go to previous message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1275
Registered: July 2009
Senior Member
File a bug, but the behavior is what I expect due to EclipseLink's lazy relationship fetching while the context is still alive. The only option for this to work as you would expect is that after an entity is detached, unfetched lazy relationships would not be reachable and accessing that relationship would require throwing an exception - the entity is detached from the context so it really should have no way of fetching lazy relationships. An exception though isn't likely what you want - well, I don't in my projects, so I'm happy to live with this behavior and use prefetching options over required lazy relationships before calling detach or using other options like serialization that make those relationships unreachable.

Previous Topic:Moxy - supported xPath version?
Next Topic:Named Query after Update before Commit
Goto Forum:
  


Current Time: Fri Dec 15 12:12:12 GMT 2017

Powered by FUDForum. Page generated in 0.01575 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software