This is not an Answer,
but just was facing kinda similar issue/purpose.
So want to share some thoughts.
in_short
If you have a detached entity, say rock_detached
,
and if you remove the id of rock_detached
,
rock_detached.setIdSql(null);
->
it seems Hibernate will not treat rock_detached
as a detached entity anymore
-- it will treat it as a new entity & insert it (when you call em.persist()
).
- Though, Im very Unsure if this is the correct way to do the thing
--ie: I do wonder what is the correct way to "convert a detached entity to a new entity" (besides setting the id to Null)
misc (-- below are not important)
Why I had such problem::
- I have 2 classes
NodeMovedEvent
& Node
NodeMovedEvent
has a Node
inside
- P1 -> I persist
NodeMovedEvent AA
with Node NN
inside -> good
- P2 ->
Node NN
is used in diff method calls & is detached from entityManger (& potentially modified)
- P3 -> I persist
NodeMovedEvent BB
with Node NN
inside -> org.hibernate.PersistentObjectException: **detached** entity passed to persist:
- I could - but I dont want to reattach by
merge()
Node NN
-- I want a new Node NN_snapshot
to be persist with the NodeMovedEvent BB
-- this kinda correspond to OP's I have an entity that I need to **copy** with JPA
- P4 -> so I came up with the idea of "setting the id to Null" -> and it works
(btw, @Audited
wasnt suitable in my case)
For a simpler code example that shows rock_detached.setIdSql(null);
::
(could made it simpler without cascade involved, but ...)

Ball
corresponds to NodeMovedEvent
above
Rock
corrsponds to Node
above
Update
@note::
If you are in a multi-threading environment,
make sure you call rock_detached.setIdSql(null);
at the last second -- right before you call em.persist()
& inside the thread calls em.persist()
- (otherwise, the
rock_detached
may have an id set again (after it was null-ed) somewhere before you switch to the thread calls em.persist()
)
- (& you should still be aware of the Cascade persist (if you are using it))
Update Misc
again, be aware that, in multi threading,
the time you pass the persist job to thread &
the time actual persist happen
is diff
-- entity may have changed in the meantime.
so, setting id to null may not guarantee the "copy effect" you want -- when in an async design
[[a bit feeling of this was not done right]]