【问题标题】:Saving entity tries to insert new record instead of merging with previous record保存实体尝试插入新记录而不是与以前的记录合并
【发布时间】:2018-01-29 18:12:39
【问题描述】:

当通过 saveAndFlush 持久化/合并父实体时,它会尝试为子实体插入新记录,而不是查找/合并现有记录。这会导致SQLIntegrityConstraintViolationException 错误。我也试过直接通过DAO拉取现有实体,将其设置为父实体中的字段,然后保存并刷新,它仍然尝试为子实体字段插入新记录。

非常感谢任何帮助!


子实体

@Entity
@Table(name = "DROPDOWN_TYPE", uniqueConstraints = {
        @UniqueConstraint(columnNames = { "DROPDOWN_TYPE_TXT" }, name = "DROPDOWN_TYPE_TXT_UK") })
public class DropdownType {

    @Id
    @Column(name = "DROPDOWN_TYPE_TXT")
    private String text;

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        DropdownType that = (DropdownType) o;

        return text.equals(that.text);
    }

    @Override
    public int hashCode() {
        return text.hashCode();
    }
}

父实体

@Entity
@Table(name = "DROPDOWN", uniqueConstraints = {
        @UniqueConstraint(columnNames = { "DROPDOWN_TXT", "DROPDOWN_TYPE_TXT" }, name = "DROPDOWN_UK") })
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Dropdown {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "DROPDOWN_OPTION_ID_GENERATOR")
    @SequenceGenerator(allocationSize = 1, name = "DROPDOWN_OPTION_ID_GENERATOR", sequenceName = "DROPDOWN_OPTION_ID_SQ")
    @Column(name = "DROPDOWN_OPTION_ID")
    private Long id;

    @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST })
    @JoinColumn(name = "DROPDOWN_TYPE_TXT", foreignKey = @ForeignKey(name = "DROPDOWN_TYPE_TXT_FK"))
    private DropdownType dropdownType;

    @Column(name = "DROPDOWN_TXT")
    private String text;

    @Column(name = "ACTIVE_FLG")
    private Boolean active;

    @Column(name = "LEGACY_FLG")
    private Boolean legacy;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public DropdownType getDropdownType() {
        return dropdownType;
    }

    public void setDropdownType(DropdownType dropdownType) {
        this.dropdownType = dropdownType;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public Boolean isActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    public Boolean isLegacy() {
        return legacy;
    }

    public void setLegacy(Boolean legacy) {
        this.legacy = legacy;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Dropdown dropdown = (Dropdown) o;

        return dropdownType.equals(dropdown.dropdownType) && text.equals(dropdown.text);
    }

    @Override
    public int hashCode() {
        int result = dropdownType != null ? dropdownType.hashCode() : 0;
        result = 31 * result + (text != null ? text.hashCode() : 0);
        return result;
    }
}

【问题讨论】:

    标签: java spring oracle hibernate hibernate-mapping


    【解决方案1】:

    如果你使用 hibernate 作为你的 JPA 提供者,当你覆盖 equals 和 hashcode 时要小心 -- see this post

    您的 JPA 提供商可能不认为您的实体是相等的,因为加载的实体实际上可能是一些 CGLIB 代理(使用instanceof 可能比比较类更好)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      • 1970-01-01
      • 2012-03-06
      • 1970-01-01
      相关资源
      最近更新 更多