Why Some Gunnar Morling that shall remain unnamed believes that claiming we do "transaction" or "unit of work" is dangerous and misleading. So we are going to offer an alternative API that is more classic in the Object Mapper universe. This API is command centric and operations do fail right away instead of being queued before a flush. Gunnar wants:
- no expectation of atomic batched operations (no transaction)
- should we have Persistence Context identity?
- probably not to avoid the side effect of updated object being flushed by a separate operation
- do you forbid relations?
- no but only store ids and prevent cascading
how
CommandSession {
save(Object o) -> persist() + flush() + clear()*
saveAll(Iterator<Object> o) -> [persist()]* + flush() + clear()*
update(Object o) -> merge() (or update()) + flush() + clear()*
updateAll(Iterator<Object> o) -> [merge() (or update())]* + flush() + clear()*
delete( ...) -> ...
find(...) -> get() + clear()*
getReference(...) -> load() + clear()*
createQuery(...).getResults() -> createQuery(...).getResults()+clear()*
clear() -> clear()
}
No cascading We do not allow cascading setting. It could be used but breaks the one command -> one explicit operation logic that we are after. With no Persistence Context clear()* means that we go for the solution without Persistence Context. This makes the implementation simple but it makes associations fail in Hibernate ORM I think as associating an uninitialized object will fail. Remember the object would have been loaded before but clear would have detached it. Update: apparently tests seem to pass. We would need to do the following for each operation:
- check the persistence context for the object being saved or updated
- replace all associated objects (direct or via collection, and nested) by their "managed" proxy
- run the operation (merge+flush+clear)
- place back the initial associated object instances back at their places
With Persistence Context That is the preferred approach as it :
- is closer to Hibernate's behavior
- solves the association requiring proxying
- makes the system faster (via first level cache)
- allows to lazily load collections etc
This requires to trick Hibernate ORM:
- fire the event and add the object to the persistence context
- do not add the operation to the flush queue
- immediately apply the flush for that specific object (or set of objects)
- this assumes associated object had been saved before but that's the general expectation of the command API in general.
batching and *All operations Depending on the underlying batching API of the dialect, we could ahve it atomic or with partial success and returning an error. Probably, we should wire the error report API to return an exception in the Command API use case Command API vs Session API No mixing will be allowed between command API and Session API. It's one or the other. Steps 1. do a simple clear focused prototype and make it work without association (but with embeddable and collection of embeddable) 2. explore the partial flush approach by looking at short circuiting the flush "queue" and to the operation right away assuming associated objects are in the persistence context 3. if that fails, fall back to the clear approach and need to impelemnent the association replaced my proxy approach |