【问题标题】:HibernateException- identifier of an instance of Domain was altered from X to YHibernateException- Domain 实例的标识符从 X 更改为 Y
【发布时间】:2016-05-28 06:12:37
【问题描述】:

当我在 spring data jpa 中更新父记录时出现异常。

这是我的代码:

父实体

@Entity
@Table(name = "CAMP")
@Getter
@Setter
public class Parent extends AbstractEntity  {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tkeygenerator")
@GenericGenerator(name = "tkeygenerator", strategy = "com.custom.TKeyGenerator",
parameters = {@org.hibernate.annotations.Parameter(name = "sequence", value = "TKEY_SEQ")})
@Column(name = "TKEY", nullable = false)    
private String id;
@ManyToOne
@JoinColumn(name = "SUB_CAT_TYPE_CODE", referencedColumnName =   "SUB_CAT_TYPE_CODE")
private Child child;
@Column(name = "DATE")
@Basic
private LocalDate date;
}  

子实体

@Entity
@Table(name = "SUB_CAT_TYPE")
@AttributeOverrides({
@AttributeOverride(name = "code", 
                   column = @Column(name = "SUB_CAT_TYPE_CODE", length = 30)),
@AttributeOverride(name = "description", 
                   column = @Column(name = "SUB_CAT_TYPE_DESC", length = 255))})
@EqualsAndHashCode(callSuper = true)
public class Child extends AbstractTypeDesc {}

测试代码

public Parent update(@PathVariable("id") String id, @Valid @RequestBody  UpdateDto dto) {

      Parent parentObj = parentRepository.findById(id);
      mapper.map(dto, parentObj); // Dozer to map incoming dto to domain                  

      childRepository.findByCode(dto.child().getCode())
                     .map(child -> { 
                           parentObj.setChild(child);
                           return child;
                      });

      return parentRepository.save(parentObj); //Exception occurs here
}    

我在尝试将父实体中子实体的代码变量更新为 fk 时遇到异常。上面写着can't alter code from X to Y

有什么建议吗?

【问题讨论】:

    标签: java hibernate jpa-2.0 spring-data-jpa


    【解决方案1】:

    我弄清楚了更新操作的上述代码块中出了什么问题。虽然不太清楚它发生的原因。将 dto 映射到域的推土机映射导致问题它正在更改子实体的值,然后在我尝试时再次更改通过setter方法设置子实体它导致“Id alter exception”,虽然我是同一件事我不知道为什么它采取不同的方式。下面是工作代码。

    测试代码应该是这样的

    public Parent update(@PathVariable("id") String id, @Valid @RequestBody       UpdateDto dto) {
    
    Parent parentObj = parentRepository.findById(id);
    
    childRepository.findByCode(dto.child().getCode())
                     .map(child -> { 
                           parentObj.setChild(child);
                           return child;
                      });
    mapper.map(dto, parentObj); // Dozer dto to domain mapping was causing problem                   
    
    return parentRepository.save(parentObj); 
    }  
    

    【讨论】:

      最近更新 更多