I have come across a situation (which I think is weird but is possibly quite normal) where I use the EntityManager.getReference(LObj.getClass(), LObj.getId()) to get a database entity and then pass the returned object to be persisted in another table.
So basically the flow was like this:
I was getting the following exception "java.lang.IllegalArgumentException: Unknown entity: com.my.persistence.L$$EnhancerByCGLIB$$3e7987d0"
After looking into it for a while, I finally figured out that it was because I was using the EntityManager.getReference() method that I was getting the above exception as the method was returning a proxy.
This makes me wonder, when is it advisable to use the EntityManager.getReference() method instead of the EntityManager.find() method?
EntityManager.getReference() throws an EntityNotFoundException if it cant find the entity being searched for which is very convenient in itself. EntityManager.find() method merely returns null if it cant find the entity.
With regards to transaction boundaries, sounds to me like you would need to use the find() method before passing the newly found entity to a new transaction. If you use the getReference() method then you would probably end up in a situation similar to mine with the above exception.
In some cases, you don't really want to load the object state, but just having a reference to it (ie a proxy). You can get this reference using the getReference() method. This is especially useful to link a child to its parent wo having to load the parent.
So in the second case the user is trying to persist a object relation so he is only trying to associate these 2 object reference and Hibernate takes care of the rest, so I feel in this case the use of getReference() methods makes sense. But will not work if you want to retrieve the object with its relationship as getReference returns only a proxy.
I am not sure how we can use EntityManager to do eager fetching of the related objects, but thats what you are trying to do.
I think you will need to anotate the entity with something like this... , it should return the actual object with the find method.
Again Merge() works with detached objects so you to have the real object and not its proxy.
posted 10 years ago
I do have the FetchType.Eager setting on the object.
I think the problem is that when I am calling the getReference() method, I am using the input parameter entity object's getClass() method which is actually a proxy class as returned by the earlier getReference() invocation. If use the static LClass.class instead, then it works fine.
So: LObj = EntityManager.getReference(LObj.getClass(), LObj.getId());
now becomes : LObj = EntityManager.getReference(L.class, LObj.getId());
Things are starting to make more sense. So in my case, I definitely need to use the EntityManager.getReference() method. But the issue still remains that it returns an instance of a proxy class, i.e., when I do a getClass() method call on the object returned by the getReference() method, the object's class is of type, $$EnhancerByCGLIB$$.
Switching from electric heat to a rocket mass heater reduces your carbon footprint as much as parking 7 cars. Tiny ad:
Devious Experiments for a Truly Passive Greenhouse!