Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Persist vs Merge different exception handling
Persist vs Merge different exception handling [message #1765678] Tue, 13 June 2017 09:07 Go to next message
Dennis Melzer is currently offline Dennis MelzerFriend
Messages: 48
Registered: December 2014
Member
Hello,

i don't understand the exception handling for persist and merge, they throw different exceptions if a bean is not valid.

A small example
class A
    @Size(min = 1, max = 64)
    private String a;


If I persist a entity i will get a ConstaintViolationException
        try {
          A a = new A();
           em.persist(a);
        } catch (final ConstraintViolationException e) {
            e.printStackTrace();
        }


If I merge (update) a entity I get a RollbackException which contains the ConstraintViolationException.
"javax.persistence.RollbackException:javax.validation.ConstraintViolationException"

So this will not work
        try {
          A a = new A();
a.setA("asassa")
           em.persist(a);

a.setA("")
//here is the issue i would expect a ConstraintViolationException
em.merge(a);
//commit will throw RollbackException
        } catch (final ConstraintViolationException e) {
            e.printStackTrace();
        }


So why I get 2 different exception?

Thanks in advance.

Dennis


[Updated on: Fri, 16 June 2017 10:13]

Report message to a moderator

Re: Persist vs Merge different exception handling [message #1765966 is a reply to message #1765678] Wed, 14 June 2017 15:51 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1389
Registered: July 2009
Senior Member
You don't, you get one exception due to the Constraint violation. The Rollback exception is because the transaction attempted to commit when it encountered the constraint violation, and is required to throw the RollbackException to wrap the cause of the rollback. It does not occur on the actual em.merge call, but when the transaction commits. Call em.flush instead after merge or persist to force things to go to the database and get exceptions before hand.

[Updated on: Wed, 14 June 2017 15:53]

Report message to a moderator

Re: Persist vs Merge different exception handling [message #1766133 is a reply to message #1765966] Fri, 16 June 2017 10:11 Go to previous messageGo to next message
Dennis Melzer is currently offline Dennis MelzerFriend
Messages: 48
Registered: December 2014
Member
Thanks for your answer. You are right, i edit the original post

Why trigger the merge no validation like the persist? I would expect a ConstraintViolation at the em.merge (like em.persist) and not at the commit with a RollbackException.

Is a em.flush not very inefficient after every merge?

[Updated on: Fri, 16 June 2017 10:13]

Report message to a moderator

Re: Persist vs Merge different exception handling [message #1766258 is a reply to message #1766133] Mon, 19 June 2017 14:26 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1389
Registered: July 2009
Senior Member
Neither persist or merge will immediately go to the database, so any constraint violation coming from the database is only guaranteed to occur on flush or on the transaction's commit.

em.flush is inefficient, and I don't recommend it, and its inefficiency is just one of the reasons why persist and merge don't immediately go to the database. It is just the only way to get things flushed to the database if you require certain database operations to have occurred, such as if you are using identity for sequencing or need to know if a constraint has been violated before continuing. It is better to let all the statements get executed at once in most cases, as it can allow for batch writing and other optimizations.

Re: Persist vs Merge different exception handling [message #1766504 is a reply to message #1766258] Thu, 22 June 2017 09:51 Go to previous messageGo to next message
Dennis Melzer is currently offline Dennis MelzerFriend
Messages: 48
Registered: December 2014
Member
Hi Chris,

i found a german blog, which explain my problem and the JSR 317: http://michael.hoennig.de/2013/05/08/bean-validation-in-jpa2-0/.

So a automatic validation is executed by persist and prePersist, but a merge will not execute a automatic validation (
These are my observations, too). After a flush or a commit the validation is executed, but in my case this is to late because i have to translate the RollbackException with the cause.
Re: Persist vs Merge different exception handling [message #1766524 is a reply to message #1766504] Thu, 22 June 2017 15:35 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1389
Registered: July 2009
Senior Member
I'm not sure I understand the crutch of the article at all, as EclipseLink does not perform or implement the JSR-317 validation spec. I don't know what they mean by EclipseLink doesn't validate new entities in the flush, and I haven't used JSR 317 myself. How did this new entity become managed if not through persist? IF the the problem is that EclipseLink is only making the validation callback during persist and then not again validating it during commit/flush - this seems strange, and I'd suggest filing an enhancement request or even a bug.

I think people are assuming that merge is a database operation when it isn't: merge merely tells JPA to take your object and put or merge changes into the managed entity. This is not equivalent to an update or save operation, despite it being treated by many as such. Validation is and should only be performed when that manage entity is synchronized with the database - on flush or transaction commit - after the application is done making changes. If you want checking done on each set method, you should add this functionality to your methods themselves.

By the way, if your method is just going to commit the transaction when it returns, calling flush might not be that ineffiicient. If you are using change tracking for instance, flush will calculate the changes and synchronize them to the database, but it would not be redone for the commit. If you are not using change tracking (weaving should be enabled for it to work generally), then the commit process will need to perform object comparisons to see if anything has changed since the flush call. You can get around this by calling em.flush and then em.clear() so that nothing remains in the context. I generally avoid flush where possible, but it can make sense if it is important to have the error upfront before continuing, or to clear memory in larger transactions.
Re: Persist vs Merge different exception handling [message #1766700 is a reply to message #1766524] Mon, 26 June 2017 09:16 Go to previous messageGo to next message
Dennis Melzer is currently offline Dennis MelzerFriend
Messages: 48
Registered: December 2014
Member
My problem is, that i don't understand, why a persist triggers a validation and not the commit?
Either merge & save triggers a valdiation directly or both will trigger by a commit. From a developer view it's strange to get different exceptions for the same validation (CVE vs Rollback cause CVE)

Chris Delahunt wrote on Thu, 22 June 2017 15:35

I think people are assuming that merge is a database operation when it isn't: merge merely tells JPA to take your object and put or merge changes into the managed entity. This is not equivalent to an update or save operation, despite it being treated by many as such.
Validation is and should only be performed when that manage entity is synchronized with the database.

That's totally fine, but how i said. Why triggers the persist immediately a validation and not the commit or flush?

I am the opinion save and merge should behave the same.
Re: Persist vs Merge different exception handling [message #1766724 is a reply to message #1766700] Mon, 26 June 2017 13:59 Go to previous message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1389
Registered: July 2009
Senior Member
I'm not sure what you are looking for - I didn't write either specifications and agreed that the behavior seems like it should be consistent on persist and merge, but can speculate they wrote it under the assumption that you would persist fully completed entities and not modify them later on, and running validation multiple times over the same entities hurts performance. But file a bug or enhancement since the behavior matches the spec requirements.
Previous Topic: NullPointerException in PersistenceUnitUtil.getIdentifier()
Next Topic:HistoryPolicy: Remove fields from history table
Goto Forum:
  


Current Time: Thu Apr 25 02:21:11 GMT 2024

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

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

Back to the top