在Hibernate中将多个关联持久化到同一实体

0

我正在创建一个聊天系统,并且具有以下数据库架构(与核心问题无关的所有内容均已删除)。

数据库架构

线程代表两个参与者之间的对话。创建(持久化)新线程时,应创建两个参与者。一个用于发送方,一个用于接收方(消息已添加到线程中,但在这种情况下不相关)。因此,我已将两个数据库表映射到两个实体。

@Entity
@Table(name = "participant")
public class Participant {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private int id;

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = Thread.class, optional = false)
    @JoinColumn(name = "thread_id")
    private Thread thread;

    // Getters and setters
}

@Entity
@Table(name = "thread")
public class Thread {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private int id;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "thread", targetEntity = Participant.class, cascade = CascadeType.ALL)
    private Set<Participant> participants = new HashSet<>();

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = Participant.class, cascade = CascadeType.ALL, optional = false)
    @JoinColumn(name = "sender_id")
    private Participant sender;

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = Participant.class, cascade = CascadeType.ALL, optional = false)
    @JoinColumn(name = "receiver_id")
    private Participant receiver;

    // Getters and setters
}

为了方便起见,Thread实体开始,participants关联应包含线程中的所有参与者,而sender和分别receiver包含对发送者和接收者的引用。因此,数据库中仅应保留两个参与者。这是我为保留新线程而编写的代码:

Thread thread = new Thread();

Participant sender = new Participant();
sender.setThread(thread);

Participant receiver = new Participant();
receiver.setThread(thread);

thread.setSubject(subject);
thread.setSender(sender);
thread.setReceiver(receiver);

Set<Participant> participants = new HashSet<>(2);
participants.add(sender);
participants.add(receiver);
thread.setParticipants(participants);

Thread saved = this.threadRepository.save(thread);

这将引发以下异常。

org.hibernate.TransientPropertyValueException:非null属性引用一个瞬态值-必须在当前操作之前保存瞬态实例:com.example.thread.entity.Participant.thread-> com.example.thread.entity.Thread

cascade在两个实体上尝试了多种属性变体,但是在所有情况下都会抛出相同的异常(尽管瞬态属性不同)。从逻辑上讲,该方法应该没有问题,因为所有要做的事情是Thread先保留实体,以便参与者在自己持久存储之前获得生成的ID。

我的映射是否有问题,或者是什么问题?谢谢!

兆赫

根据我的评论,提供了一个更详细的答案,要求提供它作为答案。

尝试解决具有不同级联类型,joincolumns和其他休眠注释的问题。通常是解决此类问题的错误方法。特别是级联应该以与您使用的方式不同的方式使用,您现在应该将其从此映射中删除。始终根据您要使用的模型来查看模型的语义/含义。级联参与者可能不是您想要的,因为在大多数情况下,参与者将创建并维护线程的独立性。因此,不要尝试在没有实际业务案例的情况下使用级联简化单个实体的保存过程。

我建议您拆分它,并独立于参与者创建/保存Thread对象。它可能需要多几行代码,但是从长远来看它们更容易理解并且更易于维护。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Hibernate 分离实体传递到持久化

Hibernate - 从多个字段到同一实体的关系

与同一实体的Hibernate递归多对多关联

Hibernate持久化实体而无需获取关联对象。仅凭身份证

如何从Hibernate中的非实体子类持久化实体

JPA:在同一实体上关联manyToMany

持久化关联实体时违反休眠约束

org.hibernate.PersistentObjectException:分离的实体传递给持久化:多对一单向

Hibernate异常:在一个单向ManyoOne关系中传递的分离实体可以持久化

Hibernate尝试两次持久化同一对象

如何使用PHP创建到同一主机的多个持久套接字连接TCP / IP

具有多对多关联实体的持久实体抛出“org.hibernate.PersistentObjectException”

'operator []'的多个重载实例化到同一签名

如何使用spring-boot和JPA持久化包含另一个未持久实体的多个相同实例的新实体?

实体会话bean-将数据持久化到表中并使用创建的ID持久化另一个表

从同一实体的内部连接获取 Hibernate 实体

休眠计数 NamedQuery 用于与同一实体的多对多关联

为什么即使在CascadeType.ALL中将实体持久化后,实体映射的字段为NULL?

独立实体通过以一对多关系持久化Spring

应该有一个外键“到”关联实体,还是“来自”关联实体?

Hibernate + JPA + spring boot org.hibernate.PersistentObjectException:分离的实体传递给持久化

JPA / Hibernate同一实体的多种表示形式

JPA 和 Hibernate 更新同一实体的某种竞争条件

与同一实体的多个一对多关系

如何从同一张表映射多个@OneToOne关联

在 Laravel 中关联同一模型的多个单个实例

CakePHP 3中对同一模型的多个关联

同一对象上的多个多态关联

Sequelize 关联到同一个表