Hibernate:如何修复"从X改为Y的实例的标识符"?

gen*_*nad 54 java hibernate hibernateexception

org.hibernate.HibernateException: identifier of an instance 
of org.cometd.hibernate.User altered from 12 to 3
Run Code Online (Sandbox Code Playgroud)

事实上,我的user表真的必须动态地改变它的价值,我的Java应用程序是多线程的.任何想法如何解决它?

Juh*_*älä 39

您是否在某处更改User对象的主键值?你不应该这样做.检查主键的映射是否正确.

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

  • 我有些问题.我的错误消息包含..从1更改为1.我的primairy键在我的实体类中设置为long但在映射文件中映射到int. (11认同)

Dan*_*lor 28

在修改其ID字段之前,必须从会话中分离实体

  • 实体管理器为此提供了一种方法。http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#detach(java.lang.Object) 您还可以检查 clear() 方法。 (3认同)

Muh*_*edy 16

在我的例子中,hbm.xml中的PK字段是"整数"类型,但在bean代码中它是long.


Anu*_*chi 6

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

private Long stockId;
    public Long getStockID() {
        return stockId;
    }
    public void setStockID(Long stockID) {
        this.stockId = stockID;
    }
Run Code Online (Sandbox Code Playgroud)

它应该在哪里

public Long getStockId() {
    return stockId;
}
public void setStockId(Long stockID) {
    this.stockId = stockID;
}
Run Code Online (Sandbox Code Playgroud)


And*_*res 5

就我而言,我解决了将 @Id 字段类型从 long 更改为 Long 的问题。


小智 5

也遇到了此错误消息,但根本原因与此处其他答案中引用的内容不同。

通用答案:确保一旦休眠加载实体,没有代码以任何方式更改该对象中的主键值。当 hibernate 将所有更改刷新回数据库时,它会抛出此异常,因为主键发生了更改。如果您没有明确执行此操作,请查找可能无意中发生这种情况的位置,可能是在仅配置了延迟加载的相关实体上。

就我而言,我使用映射框架 (MapStruct) 来更新实体。在此过程中,其他引用的实体也会更新,因为映射框架默认会这样做。我后来用新实体替换了原始实体(在数据库术语中,更改了外键的值以引用相关表中的不同行),先前引用的实体的主键已经更新,并且休眠尝试在刷新时保留此更新。