Skip to main content

JPA - why persist and merge, why not a sigle save

8 replies [Last post]
mohammadwrk
Offline
Joined: 2007-07-19
Points: 0

I don't understand why we do need two different methods for persisting and merging! Shouldn't persistence context be smart enough to distinguish between New, Manged and Detached entities? In that case all we need would be a Save method to persist/update a New/Managed/Detached entity.

Does anybody know what the rational is behind having two separate methods vs. one?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
jwenting
Offline
Joined: 2003-12-02
Points: 0

There are scenarios when you want to explicitly only create new entities or only modify existing ones.
For example some users may have update rights but not create rights on a set of tables, or (more rarely) create rights but no update rights.

mohammadwrk
Offline
Joined: 2007-07-19
Points: 0

The problem is that the merge operation does implicitly handle both cases! So using the merge operation doesn't mean always modify.
BTW, I prefer a declarative authorization.

shunya
Offline
Joined: 2010-10-01
Points: 0

Hi

I realize this is very late, but I have just started to work on JPA and I faced the same question that the author of this thread did. I think one of the reasons for two different methods could be this -

With a merge( ) operation, the ORM has to do a SELECT first to identify if a row exists, and then perform an INSERT or an UPDATE to save the data. (Atleast this is what happens with Hibernate as the underlying implementation)
So, if the application knows that it is creating a new instance, it can call the persist( ) directly and avoid the overhead of additional query.

simon_t
Offline
Joined: 2007-07-23
Points: 0

I believe there are two methods because there are two different ways of working with an EntityManager. One way is to make all changes to the objects while the EntityManager is open (while the objects are in a managed state). The other way is to load your objects in one EntityManager, close the EntityManager, make changes to the objects, then merge these changes into the managed objects of a second open EntityManager (objects that are in a detached state).

I have used the EntityManager both of these ways in an application. The first was used for batch processing. The second was used for interaction with the user.

When used the first way, there is no method that needs to be called on a managed object to have its changes persisted when commit is called. This happens automatically (see http://www.hibernate.org/hib_docs/entitymanager/reference/en/html_single...). However, the EntityManager cannot know anything about the new objects to be persisted. Hence you must explicitly tell the EntityManager of new objects that you want to have managed by calling persist on them (in much the same way that you call delete on objects you want deleted).

When used the second way merge is used for both new and detached objects (see http://www.hibernate.org/hib_docs/entitymanager/reference/en/html_single...).

Hibernate's documentation gives a little more detail on the subject. Have a look at http://www.hibernate.org/hib_docs/entitymanager/reference/en/html_single...

mohammadwrk
Offline
Joined: 2007-07-19
Points: 0

Simon, thanks for the documents.

Under section "3.7. Automatic state detection" it says "[i]The merge operation is clever enough to automatically detect whether the merging of the detached instance has to result in an insert or update. In other words, you don't have to worry about passing a new instance (and not a detached instance) to merge(), the entity manager will figure this out for you:[/i]"

It means that you can use the merge operation for both ways of working (as defined in your reply) . So why should specification bother itself to introduce a second operation (persist)?

The only reason I can think of as of now, is the performance concern. IMHO, specifications should be as simple as possible and leave these kind of fine tuning to implementations.

Witold Szczerba

I was wondering about this as well... Maybe this is because when you
really want to create new entity and you want to be 100% sure it is
new, you use #persist and if that object actually exists, the #persist
will throw an exception. With #merge, you would have to query database
first to make sure.

What's important to notice, you can always use #merge, even if your
entity is brand new. Also remember, that these two methods act a
little differently: #merge does not change the entity when it is not
managed, it creates another one and returns it, while #persist
actually modifies the object you pass to it. This is important when
you first create new object, then you can pass it another entities to
setup relation and finally you can #persist. The object you did pass
to other entities will change as well. If you would use #persist, then
it would not work.

2007/7/22, glassfish@javadesktop.org :
> I don't understand why we do need two different methods for persisting and merging! Shouldn't persistence context be smart enough to distinguish between New, Manged and Detached entities? In that case all we need would be a Save method to persist/update a New/Managed/Detached entity.
>
> Does anybody know what the rational is behind having two separate methods vs. one?
> [Message sent by forum member 'mohammadwrk' (mohammadwrk)]
>
> http://forums.java.net/jive/thread.jspa?messageID=227617
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Witold Szczerba

ERRATA:
(in last sentence) [...]If you would use #persist, then
it would not work.

Should be:
If you would use #merge, then it would not work.

2007/7/22, Witold Szczerba
:
> I was wondering about this as well... Maybe this is because when you
> really want to create new entity and you want to be 100% sure it is
> new, you use #persist and if that object actually exists, the #persist
> will throw an exception. With #merge, you would have to query database
> first to make sure.
>
> What's important to notice, you can always use #merge, even if your
> entity is brand new. Also remember, that these two methods act a
> little differently: #merge does not change the entity when it is not
> managed, it creates another one and returns it, while #persist
> actually modifies the object you pass to it. This is important when
> you first create new object, then you can pass it another entities to
> setup relation and finally you can #persist. The object you did pass
> to other entities will change as well. If you would use #persist, then
> it would not work.
>
> 2007/7/22, glassfish@javadesktop.org :
> > I don't understand why we do need two different methods for persisting and merging! Shouldn't persistence context be smart enough to distinguish between New, Manged and Detached entities? In that case all we need would be a Save method to persist/update a New/Managed/Detached entity.
> >
> > Does anybody know what the rational is behind having two separate methods vs. one?
> > [Message sent by forum member 'mohammadwrk' (mohammadwrk)]
> >
> > http://forums.java.net/jive/thread.jspa?messageID=227617
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> > For additional commands, e-mail: users-help@glassfish.dev.java.net
> >
> >
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

mohammadwrk
Offline
Joined: 2007-07-19
Points: 0

Witold, thanks for the tips on the merge method (I wasn't aware of them).
Regarding the rational behind two separate methods, I think adding more complexity to the specification just for the sake of throwing an exception vs. merging silently is not worth it.