如何解决org.hibernate.TransientObjectException:对象引用了未保存的临时实例

时间:2019-04-15 11:47:47

标签: hibernate spring-boot spring-data-jpa

我有两个实体BatchFcmFcmTopics。一个FcmTopic可以属于多个BatchFcm,因此它具有@ManyToOne关系。我尝试保存batchFcm,但是没有保存。

我已经尝试过

@ManyToOne(cascade = CascadeType.PERSIST) 
FcmTopics fcmTopics

我什至尝试了CascadeType.ALL。但这不是我的要求。 fcmtopics表将已经有数据插入其中,我需要选择一个并在batchfcm数据库中进行设置。

我尝试了@Transient批注,但是它起作用了,但列中的fcmTopics始终为空。我想要带有fcmtopics id的列。 从控制器检索时,Transient确实停止将字段fcmtopics映射到json数据中。但是我确实想找回它。

这是我的实体

  

BatchFcm

@Entity
@Table(name = "batch_fcm")
@Getter
@Setter
@NoArgsConstructor
public class BatchFcm extends AbstractEntity {

    @ManyToOne
    private FCMTopics fcmTopics;
  

FcmTopics

@Entity
@Table(name = "fcm_topics")
@Getter
@Setter
public class FCMTopics extends AbstractEntity {

    @Column(unique = true)
    private String name;

    private String description;

    private FCMTopicStatus status;

当我使用CascadeType时,我得到了重复键的ConstraintViolation异常,我知道这是由于unique = true引起的。以下是我的服务

BatchFcm fcmDetail;
if (adminFcmResource.getId() != null) {
            log.info("Updating bulk fcm log for batch id: {}, admin: {}", adminFcmResource.getId(), adminUser);
            fcmDetail = batchFcmRepository.findOne(adminFcmResource.getId());
            fcmDetail.setStatus(adminFcmResource.getStatus());
            fcmDetail.setCreatedBy(adminFcmResource.getAdminId());
            fcmDetail.setImagePath(adminFcmResource.getImagePath());
            fcmDetail.setLogo(adminFcmResource.getLogo());
            if (!InputUtil.isEmpty(adminFcmResource.getTopic())) {
                fcmDetail.setFcmTopics(fcmTopicsService.findByName(adminFcmResource.getTopic()));
            } else {
                fcmDetail.setCsvPath(adminFcmResource.getCsvPath());
            }
        } else {
            log.info("Adding bulk fcm log with csv path: {}, admin: {}", adminFcmResource.getCsvPath(), adminUser);
            fcmDetail = new BatchFcm(adminFcmResource.getTitle(),
                    adminFcmResource.getMessage(),
                    adminFcmResource.getImagePath(),
                    adminFcmResource.getAdminId(),
                    adminFcmResource.getExternalRedirectUrl());
            if (!InputUtil.isEmpty(adminFcmResource.getTopic())) {
                fcmDetail.setFcmTopics(fcmTopicsService.findByName(adminFcmResource.getTopic()));
            } else {
                fcmDetail.setCsvPath(adminFcmResource.getCsvPath());
            }
            fcmDetail.setLogo(adminFcmResource.getLogo());
            fcmDetail.setForScheduling(false);
        }
        fcmDetail.setFcmType(FCMTypes.OFFERS.ordinal());
        fcmDetail.setCreatedBy(AuthUtil.getCurrentUser().getId());
        batchFcmRepository.save(fcmDetail);

findByName确实有一个@Cacheable。 有没有办法保存数据?并将ID保留在该列中。 我已经完成@JoinColumn(referencedColumnName = "id", name = "fcm_topics_id")

3 个答案:

答案 0 :(得分:1)

请在数据库表中设置版本,因为hibernate尝试根据版本更新瞬态属性。

答案 1 :(得分:0)

我在这里看到的一个问题是您在两个实体中都缺少@id注释。 可能发生的情况是,即使您的主题已经存在于数据库中,hibernate也看不到该id,并认为它是一个新条目,必须插入。 尝试在您的实体中添加id字段。

答案 2 :(得分:0)

意味着您忘记保存对象状态