Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate JPA&x2B;禁止删除多个依赖项上的实体_Hibernate_Jpa_Spring Data Jpa - Fatal编程技术网

Hibernate JPA&x2B;禁止删除多个依赖项上的实体

Hibernate JPA&x2B;禁止删除多个依赖项上的实体,hibernate,jpa,spring-data-jpa,Hibernate,Jpa,Spring Data Jpa,我有一个用户类、一个会话类和一个消息类。用户可以是发送者和接收者。 如果我的目标是: 如果用户被删除,请保留其消息和对话 如果两个用户都被删除,则删除对话和消息 如果用户从对话中删除了他/她的最后一条消息,请保留与其他用户的对话消息 如果一个用户删除了一个对话,只删除对话中的该用户,但保留对话本身和其他用户的所有消息 在两个用户都被删除之后,删除没有用户的对话以及这些对话的消息 在我看来,我可以设置除CascadeType之外的所有CascadeType。在任何地方删除。 我必须手动检查每次

我有一个用户类、一个会话类和一个消息类。用户可以是发送者和接收者。 如果我的目标是:

  • 如果用户被删除,请保留其消息和对话
  • 如果两个用户都被删除,则删除对话和消息
  • 如果用户从对话中删除了他/她的最后一条消息,请保留与其他用户的对话消息
  • 如果一个用户删除了一个对话,只删除对话中的该用户,但保留对话本身和其他用户的所有消息
  • 在两个用户都被删除之后,删除没有用户的对话以及这些对话的消息
在我看来,我可以设置除CascadeType之外的所有CascadeType。在任何地方删除。 我必须手动检查每次删除。我想我不能设置CascadeType.Delete,例如在用户的消息上,因为我想保留它们,即使我删除了用户,如果我删除了对话的所有参与者,也要删除它们。 我不确定,但我想我不能在用户的消息上设置删除,因为如果我删除一个用户,它将清除消息列表,并删除消息

@Entity
class User {

    @Id
    @GeneratedValue
    val id: Long = 0

    @OneToMany(mappedBy = "reviewer")
    lateinit var conversations: List<Conversation>

    @OneToMany(mappedBy = "sender")
    lateinit var sentMessages: List<Message>

    @OneToMany(mappedBy = "receiver")
    lateinit var receivedMessages: List<Message>
}

@Entity
class Conversation {

    @Id
    @GeneratedValue
    val id: Long = 0

    @OneToMany(mappedBy = "conversation")
    lateinit var messages: List<Message>
}


@Entity
class Message {

    @Id
    @GeneratedValue
    val id: Long = 0

    @ManyToOne
    lateinit var conversation: Conversation

    @ManyToOne
    lateinit var sender: User

    @ManyToOne
    lateinit var receiver: User

    lateinit var message: String
}
@实体
类用户{
@身份证
@生成值
val id:Long=0
@OneToMany(mappedBy=“审阅者”)
lateinit var对话:列表
@OneToMany(mappedBy=“发件人”)
lateinit var sentMessages:列表
@OneToMany(mappedBy=“接收者”)
lateinit变量receivedMessages:列表
}
@实体
课堂对话{
@身份证
@生成值
val id:Long=0
@OneToMany(mappedBy=“对话”)
lateinit var消息:列表
}
@实体
类消息{
@身份证
@生成值
val id:Long=0
@许多酮
lateinit var对话:对话
@许多酮
lateinit var发送方:用户
@许多酮
lateinit var接收器:用户
lateinit var消息:字符串
}

对于Hibernate来说,您设置的非琐碎规则太多,无法立即处理

我建议使用聚合和聚合根的DDD概念来分解模型,在聚合中使用级联,并与两者之间的事件进行通信

我看到两个聚合:
用户
对话
Conversation
聚合由作为聚合根的
Conversation
和作为附加实体的
消息组成

用户
中删除
消息
列表,并在
会话存储库
中提供查找方法

您描述的所有逻辑都包含在
User
UserRepository
Conversation
ConversationRepository
中的方法中。
User*
类可以委托给
ConversationRepository
来操作
Conversation
s和
Message
s


通过这种方法,实现所需的逻辑应该更容易实现、测试和理解。实际上,使用直接SQL而不是JPA实现许多步骤可能更容易(也可能更快)。当然,您必须注意JPAs一级缓存不会过时。

谢谢!所以这个逻辑太复杂了,无法用hibernate实现,我必须在我的业务逻辑中的某个地方实现它。一个建议是不要对多个关系字段使用列表类型。它会导致笛卡尔结果。您的意思是在对话和用户中没有消息列表?我的意思是不要将它们全部映射为列表
对话
发送消息
接收消息
用户
实体中。看一看:谢谢!我重新设计了我的实体。