-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add manually publishing cascade events in implementation of DAOs instead of using EntityListeners #3342
Conversation
31bdcd1
to
7aaeb81
Compare
f186ffa
to
95c0cd1
Compare
return user; | ||
|
||
final UserImpl user = manager.find(UserImpl.class, id); | ||
if (user != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd change it to
if (user == null) {
return Optional.empty();
}
eventService.publish(new BeforeUserRemovedEvent(user));
manager.remove(user);
return Optional.of(user);
as Optional.ofNullable(user)
causes another null check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach won't propagate the original exception
941287e
to
bae2759
Compare
f22e6a6
to
3d5e5d5
Compare
public class RemovalContext { | ||
private Exception cause; | ||
public class CascadeContext { | ||
private ApiException cause; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, REST-api oriented exception looks a bit strange here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same as throwing REST-api oriented exception by Dao. But we do it. :) And we save original REST-api oriented exception that is thrown by listener for rethrowing
@@ -159,7 +161,9 @@ protected FactoryImpl doUpdate(FactoryImpl update) throws NotFoundException { | |||
if (update.getWorkspace() != null) { | |||
update.getWorkspace().getProjects().forEach(ProjectConfigImpl::prePersistAttributes); | |||
} | |||
return manager.merge(update); | |||
FactoryImpl merged = manager.merge(update); | |||
manager.flush(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is those changes are necessary if we didn't publish any events here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because this operation can be performed by listener. And then integrity exception will be catched in wrong place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can hardly imagine the listener which will create factory in some case :)) But for purposes of uniformity it's ok.
* <p>If the method throws an exception it will be set to context | ||
* to break event publishing and rethrow exception. | ||
* Original exception can be rethrown to publisher | ||
* or it can be wrapped in {@link SecurityException} instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SecurityException
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oooops 😄
2076f6d
to
8d6e87d
Compare
064ed10
to
f0bd904
Compare
c77e373
to
77f1da4
Compare
Build success. https://ci.codenvycorp.com/job/che-pullrequests-build/1563/ |
d9bf21c
to
2200464
Compare
a61907b
to
2289e59
Compare
…ration as cascade. Also contains following changes: - Fixes rethrowing original exception while cascade operation. - Add manually publishing cascade events in implementation of DAOs instead of using EntityListeners. - Add flushing of data by EntityManager#flush to produce consistency exception in right place. - Add CascadeEventLister that is able to throw any of Exception. If listener throws exception then all data changes should be canceled. - Add base events(PersistEvent, RemoveEvent, UpdateEvent). CascadeEventService throws only right exceptions for each use case. When thrown by listener exception should not be thrown by contract of this operation, then it will be wrapped into ServerException.
2289e59
to
359bd73
Compare
Build success. https://ci.codenvycorp.com/job/che-pullrequests-build/1606/ |
What does this PR do?
Add:
What issues does this PR fix or reference?
#3399
Previous behavior
Post[Persist|Remove|Update] events are thrown EntityListener, and it is not allowed to change(store new, remove or update existing) any objects on these events.
User is not able to see original exception while cascade removing.
New behavior
New approach allows us to perform any operations on post events or rollback transaction if is fails.
So post events must be thrown by implementations of DAOs. It allows to perform any operation on event and rollback transaction if one of subscriber fails.
To fails original operation event subscriber should extend
CascadeEventSubscriber