spring-data-jpa Spring JPA / Hibernate -从未设置外键

vaj7vani  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(234)

我有两个Oracle表,它们之间的关系为1:M:

EVENT(ID, NAME, DATE)

EVENT_LOG(ID, EVENT_ID, COMPLETED)
  • EVENT的PK=ID
  • EVENT_LOG在事件ID上具有PK=ID和FK=事件ID

我希望使用Spring JPA将这些数据持久化到数据库中,因此我使用@OneToMany@ManyToOne注解构建了我的实体,如下所示(为了清楚起见,省略了一些细节):

@Entity
@Table(name = "EVENT")
public class EventEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "DATE"")
    private OffsetDateTime date;

    @OneToMany(mappedBy = "eventEntityDetails", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<EventLogEntity> eventLogs;

    ...
}

@Entity
@Table(name = "EVENT_LOG")
public class EventLogEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "ID")
    private Long id;

    @Column(name = "EVENT_ID")
    private long eventId;

    @Column(name = "COMPLETED")
    private int completed;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "E_ID", referencedColumnName = "ID")
    private EventEntity eventEntityDetails;

    // ...
}

为了持久保存我的EVENT和EVENT_LOG,我有这个方法。它接收EntityDto对象,我将其Map到一个新的实体示例,然后我创建新的EventLogEntity,设置它的COMPLETED值,并调用存储库来保存我的事件。
在这个阶段,我不能设置EventLog.EVENT_ID,因为在这个阶段EVENT.ID还没有生成,所以我期望Hibernate会为我处理这个问题。然而,这是错误的,我想我在这个方法中或者在我的实体中的@OneToMany@ManyToOne注解中遗漏了一些东西:

private EventEntity saveEvent(EventDto eventDto) {

    EventEntity eventEntity = new EventEntity();

    ModelMapper modelMapper = new ModelMapper();
    modelMapper.map(eventDto, eventEntity);

    List<EventLogEntity> eventLogs = new ArrayList<EventLogEntity>();

    EventLogEntity eventLogEntity = new EventLogEntity();
    eventLogEntity.setCompleted(1);
    eventLogs.add(eventLogEntity);

    eventEntity.setEventtLogs(eventLogs);

    EventEntity storedEvent = eventRepository.saveAndFlush(eventEntity);

    return storedEvent;
}

问题

上面对safeAndFlush()的调用将把我的Event和EventLog保存到它们的表中,但是EVENT_LOG.EVENT_ID(它是EVENT.ID的FK)总是设置为0,而不是设置为EVENT. ID中的值。
我希望将其设置为EVENT的ID,如下例所示:

EVENT(1, 'open_door', 20220210T11:55:10)

EVENT_LOG(1, 1, 1)

,但我反而得到:

EVENT(1, 'open_door', 20220210T11:55:10)

EVENT_LOG(1, 0, 1)
nvbavucw

nvbavucw1#

我认为在刷新之前,必须将EventEntity对象赋给EventLogEntity

EventLogEntity eventLogEntity = new EventLogEntity();
eventLogEntity.setCompleted(1);
eventLogEntity.setEventEntityDetails(eventEntity);
eventLogs.add(eventLogEntity);

看看有没有帮助。

更新:我认为您需要的是以下内容:

@Entity
@Table(name = "EVENT")
public class EventEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "ID")
    private Long id;

    @OneToMany(mappedBy = "event", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<EventLogEntity> eventLogs;

    ...
}

@Entity
@Table(name = "EVENT_LOG")
public class EventLogEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "ID")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "EVENT_ID")
    private EventEntity event;

}

请注意以下几点:

  • 我删除了referencedColumnName信息,因为默认情况下使用引用表的主键,这在我们的示例中是很好的
  • 我删除了显式的EVENT_ID列,该列是您声明为类的一部分。该列将作为event字段上附加@ManyToOne注解的一部分自动创建。
  • 我将eventEntityDetails字段简单地重命名为event

我很肯定这个解决方案会起作用的!请让我知道。

相关问题