org.hibernate.HibernateException: identifier of an instance 
of org.cometd.hibernate.User altered from 12 to 3

实际上,我的 user 表确实必须动态地更改其值,我的Java应用程序是多线程。有什么想法如何解决?

有帮助吗?

解决方案

您是否正在更改某个地方用户对象的主要密钥值?你不应该那样做。检查主键的映射是否正确。

您的映射XML文件或映射注释是什么样的?

其他提示

您必须在修改其ID字段之前将您的实体分离为会话

就我而 long.

就我而言,我解决了它将@ID字段类型从长时间更改为长。

在我的情况下,Geters和Setter名称与变量名不同。

private Long stockId;
    public Long getStockID() {
        return stockId;
    }
    public void setStockID(Long stockID) {
        this.stockId = stockID;
    }

应该在哪里

public Long getStockId() {
    return stockId;
}
public void setStockId(Long stockID) {
    this.stockId = stockID;
}

在我的特殊情况下,这是由我的服务实施中的一种方法引起的,需要弹簧 @Transactional(readOnly = true) 注解。一旦我补充说,问题就解决了。不过,不寻常,这只是一个精选陈述。

就我而言,模板具有错别字,因此而不是检查等效性(==),而是使用分配等价(=)。

因此,我从:

if (user1.id = user2.id) ...

if (user1.id == user2.id) ...

现在一切都很好。因此,还要检查您的观点!

在更改ID时,请确保您不会尝试多次使用相同的用户对象。换句话说,如果您在批处理类型操作中做某事:

User user = new User();  // Using the same one over and over, won't work
List<Customer> customers = fetchCustomersFromSomeService();
for(Customer customer : customers) {
 // User user = new User(); <-- This would work, you get a new one each time
 user.setId(customer.getId());
 user.setName(customer.getName());
 saveUserToDB(user);
}

我也面临这个问题。

目标表是一个关系表,从不同表接线了两个ID。我对价值组合有独特的约束,取代了PK。更新元组的值之一时,会发生此错误。

这就是桌子的样子(mysql):

CREATE TABLE my_relation_table (
  mrt_left_id BIGINT NOT NULL,
  mrt_right_id BIGINT NOT NULL,
  UNIQUE KEY uix_my_relation_table (mrt_left_id, mrt_right_id),
  FOREIGN KEY (mrt_left_id)
    REFERENCES left_table(lef_id),
  FOREIGN KEY (mrt_right_id)
    REFERENCES right_table(rig_id)
);

实体课程 RelationWithUnique 实体看起来基本上是这样:

@Entity
@IdClass(RelationWithUnique.class)
@Table(name = "my_relation_table")
public class RelationWithUnique implements Serializable {

  ...

  @Id
  @ManyToOne
  @JoinColumn(name = "mrt_left_id", referencedColumnName = "left_table.lef_id")
  private LeftTableEntity leftId;

  @Id
  @ManyToOne
  @JoinColumn(name = "mrt_right_id", referencedColumnName = "right_table.rig_id")
  private RightTableEntity rightId;

  ...

我修复了

// usually, we need to detach the object as we are updating the PK
// (rightId being part of the UNIQUE constraint) => PK
// but this would produce a duplicate entry, 
// therefore, we simply delete the old tuple and add the new one
final RelationWithUnique newRelation = new RelationWithUnique();
newRelation.setLeftId(oldRelation.getLeftId());
newRelation.setRightId(rightId);  // here, the value is updated actually
entityManager.remove(oldRelation);
entityManager.persist(newRelation);

非常感谢PK的提示,我只是错过了。

问题也可以在不同类型的对象的PK(在您的情况下使用),然后键入您要求Hibernate获取 session.get(type, id);.

在我的情况下,错误是 identifier of an instance of <skipped> was altered from 16 to 32. 。对象的PK类型是 Integer, ,冬眠被要求 Long 类型。

就我而言,这是因为该属性很长,但在映射XML中int,此例外应该更清楚

如果您使用的是Spring MVC或Spring Boot尝试避免:@modelattribute(“用户”) 在一个反对者和其他控制器中model.addattribute(“用户”,userrepository.findone(someid);

这种情况可能会产生这种错误。

这是一个古老的问题,但是我将添加我的特定问题的修复程序(Spring Boot,JPA使用Hibernate,SQL Server 2014),因为它与此处包含的其他答案不完全匹配:

我有一个外键,例如my_id ='12345',但是引用列中的值是my_id ='12345'。它有一个 额外的空间 在冬眠的最后不喜欢。我删除了空间,修复了允许此额外空间的代码部分,一切正常。

面对同样的问题。我在2个豆之间进行了调查。在bean中,AI将变量类型定义为整数,而Bean BI则定义了相同的变量。我将它们都更改为整数。这解决了我的问题。

这是您的更新方法中的问题。在保存更改之前,只需实例新用户,您就可以了。如果您使用DTO和实体类之间的映射,则在映射之前进行映射。

我也有这个错误。我有用户对象,试图更改其位置,位置是用户表中的FK。我解决了这个问题

@Transactional
public void update(User input) throws Exception {

    User userDB = userRepository.findById(input.getUserId()).orElse(null);
    userDB.setLocation(new Location());
    userMapper.updateEntityFromDto(input, userDB);

    User user= userRepository.save(userDB);
}  

我通过实现依赖对象的新实例来解决此问题。例如

instanceA.setInstanceB(new InstanceB());
instanceA.setInstanceB(YOUR NEW VALUE);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top