Reputation: 431
I have a class of users that includes a list of books objects. Once user's record is created all the books that he borrows will added to the list of books in his object. Once user removes his profile the record and history of the borrowed books need to be kept.
Many registered users may frequently borrow books and delete their profiles. To make the information retrieval faster (for example, retrieve a list of active users) I do not want to keep the record of deleted profiles in the same table that I keep records of active profiles.
Currently once user wants to delete his profile I put that object (userObj) in deactiveUserObj and remove the user's record from User table and try to save the deactiveUserObj to keep the record of deactivated record in that table but it throws the following exception.
My options: I know that I can create another table and keep the id of active users there or have an extra column of type boolean for user class and make it false to indicate the record is deleted. However I am not sure which of these three approaches is better or if there is another approach that I have not considered.
User class
@Entity
public class User{
private long id;
private List<Book> books;
...
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public List<Book> getBooks() {
return books;
}
....
Book class
@Entity
public class Book{
private long id;
private string name;
...
}
Deleted Object class
@Entity
public class DeactiveUsers{
private long id;
private date deactiveSince;
private List<Book> books;
...
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public List<Book> getBooks() {
return books;
}
....
}
MyCode
1) code to retrieve an object of user class goes here
2) code to copy object of user class into deletedObject goes here
3) 3.1 - session.delete(userObj);
3.2 - session.saveOrUpdate(deactiveUsersObj);
The code runs into following error
SEVERE: org.hibernate.ObjectDeletedException: deleted object would be re-saved by
cascade (remove deleted object from associations): [com.project.Book#1]
Upvotes: 2
Views: 756
Reputation: 40315
First: The reason for your error is you have cascade set to ALL on User.getBooks(), which will delete its books when you delete the User. Then, in the same session, you attempt to re-add the deleted objects when you add the DeactivatedUser back (which contains the same Books -- while you don't show your code for constructing a DeactivatedUser from a User, I presume you are making a shallow copy of Books, as you should). Change cascade to SAVE_UPDATE.
Second: I highly recommend keeping them all in the same table with a flag field that indicates if they are deleted or not.
Do not optimize prematurely. Unless you've actually benchmarked your code and found a bottleneck in database queries related to active vs. inactive users, there's no benefit to over-complicating your schema and business logic. Most SQL servers are very efficient, it is unlikely that you will find a bottleneck there for your application.
Doing it this way, an easy way to improve performance is to simply create an index on the deleted flag field.
With Hibernate you will be able to easily select active vs. deleted users via a Criteria.
Additionally, and most importantly, by not having a separate User and DeactiveUser object, you won't have to maintain the two objects in parallel, and you won't have to duplicate code that can operate on both types.
Upvotes: 2