Persist vs Merge different exception handling [message #1765678] |
Tue, 13 June 2017 09:07 |
Dennis Melzer 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 |
Chris Delahunt 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 #1766524 is a reply to message #1766504] |
Thu, 22 June 2017 15:35 |
Chris Delahunt 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.
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04711 seconds