2

我有一类用户,其中包括书籍对象列表。创建用户记录后,他借阅的所有书籍都将添加到他的对象中的书籍列表中。一旦用户删除他的个人资料,就需要保留借阅书籍的记录和历史记录。

许多注册用户可能会经常借书并删除他们的个人资料。为了使信息检索更快(例如,检索活动用户列表),我不想将已删除配置文件的记录保存在我保存活动配置文件记录的同一个表中。

目前,一旦用户想要删除他的个人资料,我将该对象(userObj)放入 deactiveUserObj 并从 User 表中删除用户的记录,并尝试保存 deactiveUserObj 以将停用记录的记录保留在该表中,但它会引发以下异常。

我的选择:我知道我可以创建另一个表并将活动用户的 id 保留在那里,或者为用户类添加一个布尔类型的额外列,并将其设置为 false 以指示记录已被删除。但是,我不确定这三种方法中哪一种更好,或者是否还有另一种我没有考虑过的方法。

用户类

@Entity
public class User{

   private long id;
   private List<Book> books;
   ...

   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   public List<Book> getBooks() {
        return books;
   }
   ....

书类

@Entity
public class Book{

   private long id;
   private string name;
   ...
}

已删除的对象类

@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;
   }
   ....    

}

我的代码

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);

代码遇到以下错误

SEVERE: org.hibernate.ObjectDeletedException: deleted object would be re-saved by 
        cascade (remove deleted object from associations): [com.project.Book#1]
4

1 回答 1

2

首先:您的错误原因是您在 User.getBooks() 上将级联设置为 ALL,这将在您删除用户时删除其书籍。然后,在同一个会话中,当您添加 DeactivatedUser 时,您尝试重新添加已删除的对象(其中包含相同的书籍 - 虽然您没有显示用于从用户构造 DeactivatedUser 的代码,但我认为您是制作书籍的浅拷贝,你应该这样做)。将级联更改为 SAVE_UPDATE。

其次:我强烈建议将它们全部保存在同一个表中,并带有一个标志字段,指示它们是否被删除。

不要过早优化。除非您实际上对代码进行了基准测试,并发现与活跃用户和非活跃用户相关的数据库查询存在瓶颈,否则过度复杂的架构和业务逻辑没有任何好处。大多数 SQL 服务器都非常高效,您不太可能会在那里找到应用程序的瓶颈。

这样做,提高性能的一种简单方法是简单地在已删除标志字段上创建索引。

使用 Hibernate,您将能够通过标准轻松选择活跃用户和已删除用户。

此外,最重要的是,由于没有单独的 User 和 DeactiveUser 对象,您不必并行维护这两个对象,也不必复制可以对这两种类型进行操作的代码。

于 2013-08-07T00:49:46.437 回答