Skip to content
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 cascade removal for known entities #2031

Merged
merged 1 commit into from
Aug 3, 2016

Conversation

voievodin
Copy link
Contributor

@voievodin voievodin commented Aug 3, 2016

What does this PR do?

Introduces cascade removal strategies, which are:

  • Use orphanRemoval or @CascadeOnDelete those strategies require entries to declare
    either bidirectional mapping, or mapping present on owning side, for example Profile depends on Userwhile User doesn't know anything about profile, so for removing profile along with a user we have to declare Profile mapping on User object side, and mark the dependency with orphanRemoval, this is not always possible as objects may be in separate modules and it will produce circular dependencies.
  • Use foreignKeyDefinition for defining foreign keys e.g.:
@JoinColumn(foreignKey = 
            @ForeignKey(name = "USER_FK",
                        foreignKeyDefinition = "FOREIGN KEY(user_id) REFERENCES User(id) ON DELETE CASCADE"))

While this strategy doesn't require to define dependenies on owning side, it is RDBMS specific,
another problem is that it won't affect Caches(L2 is a problem here) as all the removal stuff will be performed by the database.

  • Use JPA events + EventService for removing entities.
    As EventService is synchronous we can publish events and wait while all the notifiers proceed those events. On the other hand we don't use any native queries and always remove entries using EntityManager#remove method, which means that JPA takes care of removal and publishes entity related events. In that case we can connect JPA events and EventService events to allow another modules/entities/components to react on the removal. All the database interaction methods are marked with the @Transactional annotation which may be nested.
    The example:
-> Transaction begins
-> before User#remove() 
       -> @PreRemove(User) event is published by JPA, 
       -> @PreRemove(User) event is handled and `BeforeUserRemoved` event is published to `EventService`
       -> BeforeUserRemoved event is catched by profile subscriber, 
       -> before ProfileDao#remove(profile)
             -> @PreRemove(Profile) event is published
            // ...
       -> ProfileDao#remove(profile) performed
      // ...
-> User#remove() performed
-> Transaction committed/rolled back

If any entry removal fails, then transaction will be rolled back and all the data will be in consistent state.
Another nice thing in this strategy is that we can create application level components which may react on such kind of events and rollback transactions on the application level(which is useful for recipes and stacks their removal will be based on permissions).
It is still possible and preferable to use orphanRemoval for those entities which are not root model entities, for instance Workspace relies on the WorkspaceConfig with orphanRemoval attribute.

I implemented the last strategy as it is the most appropriate. Along with that i changed
current Local dao implementations to use self monitor for locking, as it allows to extend them with a new functionality which may also be thread-safe as client becomes allowed to use instance locks, this may be needed for migration tools.

What issues does this PR fix or reference?

#1803

Previous Behavior

No cascade removals

New Behavior

All the entries removed when any of entries which they depend on is removed.

Tests written?

Yes

@skabashnyuk, @sleshchenko, @akorneta please review

</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that we need testng with compile scope?

@skabashnyuk
Copy link
Contributor

ok

@sleshchenko
Copy link
Member

LGTM

@akorneta
Copy link
Contributor

akorneta commented Aug 3, 2016

ok

@voievodin voievodin merged commit 33fb91f into jpa-integration Aug 3, 2016
@voievodin voievodin deleted the jpa-cascade-removal branch August 3, 2016 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants