在OneToMany JPA中更新父项时,将创建新的子实体

时间:2017-04-14 02:08:16

标签: java hibernate jpa spring-data-jpa one-to-many

您好我有一个父子表如下。有以下问题。 我正在使用Spring Data Repository(org.springframework.data.repository)

问题1 虽然我正在保持父子项也会插入,但是当我尝试更新父项时(父项和子项中都存在新的更改),新的子项将插入子表中并更新数据而不是更新旧的子数据。

问题2 我在这里进行补丁调用,数据来自UI作为json,我有一些审计跟踪字段,如createdBy,createdTimestamp,updatedBy,updatedTimestamp。这些字段将在Create&中的后端服务中填充。分别更新操作。现在在更新操作中,我的dto没有createdBy&的任何值。 createdTimestamp,所以在DB中它被设置为null。我在这里很困惑,我正在使用补丁调用然后它应该保留旧的值吗?

请建议如果我错过任何

父:

@Id
@SequenceGenerator(name = "DIVERSITY_TEMPLATE_ID", sequenceName = "DIVERSITY_TEMPLATE_ID", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DIVERSITY_TEMPLATE_ID")
@Column(name = "DIVERSITY_TEMPLATE_ID")
private Integer diversityTemplateId;

@Column(name = "LABEL")
private String label;

@Column(name = "RELATIONSHIP_TYPE")
private String relationshipType;

@Column(name = "CREATED_BY")
private String createdBy;

@Column(name = "CREATED_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date createdTimestamp;

@Column(name = "UPDATED_BY")
private String updatedBy;

@Column(name = "UPDATED_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date updatedTimestamp;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "diversityTemplate", fetch = FetchType.LAZY)
private List<DiversityTemplateAttribute> attributes = new ArrayList<>();

/**
 * @return the attributes
 */
public List<DiversityTemplateAttribute> getAttributes() {
    return attributes;
}

/**
 * @param attributes the attributes to set
 */
public void setAttributes(List<DiversityTemplateAttribute> attributes) {
    for (DiversityTemplateAttribute diversityTemplateAttribute : attributes) {
        diversityTemplateAttribute.setDiversityTemplate(this);
    }
    this.attributes = attributes;
}

子:

@Id
@SequenceGenerator(name = "DIVERSITY_TEMPLATE_ATTR_ID", sequenceName = "DIVERSITY_TEMPLATE_ATTR_ID", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DIVERSITY_TEMPLATE_ATTR_ID")
@Column(name = "DIVERSITY_TEMPLATE_ATTR_ID")
private Integer diversityTemplateAttributeId;

@Column(name = "AA")
private String aa;

@Column(name = "BB")
private String bb;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DIVERSITY_TEMPLATE_ID", referencedColumnName = "DIVERSITY_TEMPLATE_ID")
private DiversityTemplate diversityTemplate;

示例更新JSON

{
"diversityTemplateId": 681,
"label": "SAMPLE_LABEL_463_UPDATED",
"relationshipType": "Married",
"attributes": [{
    "diversityTemplateId": 681,
    "diversityTemplateAttributeId": 3006,
    "aa": "AA",
    "bb": "BB Updated",
}, {
    "diversityTemplateId": 681,
    "diversityTemplateAttributeId": 3006,
    "aa": "aa Updated",
    "bb": "bb"
}
]

}

服务层:

DiversityTemplate updatedEntity = diversityTemplateRepository.save(diversityTemplate);

问题3 如果将Entity对象(当我从GET / CREATE操作获取它)映射到DTO对象时,我无法在子对象中设置FK id,所以作为一种解决方法,我正在迭代对象的子列表&amp;手动设置子DTO中的父pk,有没有更好的方法来做到这一点。我在子ENTITY类中添加了一个临时列,其中pk列名与Parent相同,但是它的值也变为零,有没有更好的方法?请在下面找到我的工作。

DiversityTemplate updatedEntity = diversityTemplateRepository.save(diversityTemplate);

    List<DiversityTemplateAttributeDTO> attrbiteList = new ArrayList<>();
    for (DiversityTemplateAttribute attribute : updatedEntity.getAttributes()) {
        DiversityTemplateAttributeDTO attributeDTO = resourceMapper
                .convertToDiversityTemplateAttributeDTO(attribute);
        attributeDTO.setDiversityTemplateId(updatedEntity.getDiversityTemplateId());
        attrbiteList.add(attributeDTO);
    }

    DiversityTemplateDTO updatedDiversityTemplateDTO = resourceMapper.convertToDiversityTemplateDTO(updatedEntity);
    diversityTemplateDTO.setAttributes(attrbiteList);

请建议

1 个答案:

答案 0 :(得分:0)

我和你都有同样的问题。

答案1:我最终要做的是在@OneToMany上将orphanRemoval标志设置为true。如果执行此操作,请注意您不能再将子级列表设置为等于新列表,否则它将通过并出错。您必须根据要删除和添加的内容来删除和追加。

答案2:您在父类的顶部缺少@EntityListeners(AuditingEntityListener.class),但是以防万一它不起作用,这是我以前用来使其工作的链接{{3} }

答案3:未设置ID的原因是因为在Java代码中,您必须设置对子代中父代的引用。 即child.setDiversityTemplate(parent); 完成后,它将正确地映射到表中,并且可以毫无问题地检索它。