org.hibernate.HibernateException: identifier of an instance
of org.cometd.hibernate.User altered from 12 to 3
实际上,我的user
表必须动态地改变它的值,我的Java应用程序是多线程的。
任何想法如何解决它?
答案 0 :(得分:36)
您是否正在某处更改User对象的主键值?你不应该这样做。检查主键的映射是否正确。
您的映射XML文件或映射注释是什么样的?
答案 1 :(得分:26)
在修改ID字段
之前,您必须从会话中分离您的实体答案 2 :(得分:16)
就我而言,hbm.xml中的PK字段的类型为“整数”,但在bean代码中它是long
。
答案 3 :(得分:4)
在我的情况下,我解决了它将@Id字段类型从long更改为Long。
答案 4 :(得分:4)
在我看来,getter和setter名称与Variable name不同。
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;
}
答案 5 :(得分:3)
在我的特定情况下,这是由我的服务实现中需要spring @Transactional(readOnly = true)
注释的方法引起的。一旦我补充说,问题就解决了。但不寻常,这只是一个选择声明。
答案 6 :(得分:3)
在我的情况下,模板有一个拼写错误,所以不是检查等价(==),而是使用赋值等于(=)。
所以我改变了模板逻辑:
if (user1.id = user2.id) ...
到
if (user1.id == user2.id) ...
现在一切都很好。所以,也要检查你的观点!
答案 7 :(得分:3)
确保在更改ID时不要多次尝试使用同一个User对象。换句话说,如果您在批处理类型操作中执行某些操作:
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);
}
答案 8 :(得分:2)
我也面临这个问题。
目标表是一个关系表,连接来自不同表的两个ID。我对值组合有一个UNIQUE约束,取代了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类看起来基本上是这样的:
@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的暗示,我只是错过了它。
答案 9 :(得分:1)
问题也可以出现在不同类型的对象的PK中(&#34;用户&#34;在你的情况下)并输入你要求hibernate获取session.get(type, id);
。
在我的情况下,错误是identifier of an instance of <skipped> was altered from 16 to 32
。
对象的PK类型为Integer
,hibernate被要求Long
类型。
答案 10 :(得分:0)
在我的情况下,这是因为属性在对象上很长但在映射xml中是int,这个异常应该更清楚
答案 11 :(得分:0)
如果您使用的是Spring MVC或Spring Boot,请尽量避免: @ModelAttribute(&#34; user&#34;)在一个控制器和其他控制器中 model.addAttribute(&#34; user&#34;,userRepository.findOne(someId);
这种情况可能会产生这样的错误。
答案 12 :(得分:0)
这是一个老问题,但我要为我的特定问题添加修复程序(Spring Boot,JPA使用Hibernate,SQL Server 2014),因为它不完全匹配此处包含的其他答案:
我有一个外键,例如my_id =&#39; 12345&#39;,但引用列中的值为my_id =&#39; 12345&#39;。它最终有一个 额外空间 ,而hibernate并不喜欢。我删除了空间,修复了允许这个额外空间的代码部分,一切正常。
答案 13 :(得分:0)
面对同样的问题。 我有两个豆之间的关联。在bean A中,我将变量类型定义为Integer,在bean B中,我将变量定义为Long。 我将它们都更改为Integer。这解决了我的问题。
答案 14 :(得分:0)
这是您的更新方法中的问题。在保存更改之前,只需实例化新用户,就可以了。如果您在DTO和Entity类之间使用映射,那么请在映射之前进行此操作。
我也有这个错误。我有用户对象,试图更改他的位置,用户表中的位置为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);
}
答案 15 :(得分:0)
我通过实例化一个依赖对象的新实例来解决这个问题。例如
instanceA.setInstanceB(new InstanceB());
instanceA.setInstanceB(YOUR NEW VALUE);
答案 16 :(得分:0)
也遇到了此错误消息,但根本原因与此处其他答案中所引用的内容有所不同。
通用答案: 确保一旦休眠加载了一个实体,任何代码都不会以任何方式更改该对象中的主键值。当休眠将所有更改刷新回数据库时,它会抛出此异常,因为主键已更改。如果您未明确进行此操作,请寻找可能无意间发生这种情况的地方,也许是在仅配置了LAZY加载的相关实体上。
就我而言,我正在使用映射框架(MapStruct)更新实体。在此过程中,还更新了其他引用的实体,因为映射框架默认会这样做。后来我用新实体替换了原始实体(按照数据库术语,更改了外键的值以引用相关表中的另一行),先前引用的实体的主键已经更新,并且休眠尝试在刷新时继续执行此更新。
答案 17 :(得分:0)
就我而言,我在数据库中有一个带有重音的主键,但在其他表中它的外键没有。出于某种原因,MySQL 允许这样做。
答案 18 :(得分:0)
您似乎更改了实例的标识符 由 JPA 实体上下文管理的 org.cometd.hibernate.User 对象。 在这种情况下,使用适当的 id 创建新的 User 实体对象。并设置它而不是原始的 User 对象。