Hibernate: How to fix “identifier of an instance altered from X to Y”?

非 Y 不嫁゛ 提交于 2019-11-27 07:56:41

Are you changing the primary key value of a User object somewhere? You shouldn't do that. Check that your mapping for the primary key is correct.

What does your mapping XML file or mapping annotations look like?

You must detach your entity from session before modifying its ID fields

In my case, the PK Field in hbm.xml was of type "integer" but in bean code it was long.

In my case, I solved it changing the @Id field type from long to Long.

In my case getters and setter names were different from Variable name.

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

where it should be

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

In my particular case, this was caused by a method in my service implementation that needed the spring @Transactional(readOnly = true) annotation. Once I added that, the issue was resolved. Unusual though, it was just a select statement.

In my case, a template had a typo so instead of checking for equivalency (==) it was using an assignment equals (=).

So I changed the template logic from:

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

to

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

and now everything is fine. So, check your views as well!

Make sure you aren't trying to use the same User object more than once while changing the ID. In other words, if you were doing something in a batch type operation:

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);
}

I was facing this issue, too.

The target table is a relation table, wiring two IDs from different tables. I have a UNIQUE constraint on the value combination, replacing the PK. When updating one of the values of a tuple, this error occured.

This is how the table looks like (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)
);

The Entity class for the RelationWithUnique entity looks basically like this:

@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;

  ...

I fixed it by

// 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);

Thanks a lot for the hint of the PK, I just missed it.

Problem can be also in different types of object's PK ("User" in your case) and type you ask hibernate to get session.get(type, id);.

In my case error was identifier of an instance of <skipped> was altered from 16 to 32. Object's PK type was Integer, hibernate was asked for Long type.

In my case it was because the property was long on object but int in the mapping xml, this exception should be clearer

If you are using Spring MVC or Spring Boot try to avoid: @ModelAttribute("user") in one controoler, and in other controller model.addAttribute("user", userRepository.findOne(someId);

This situation can produce such error.

This is an old question, but I'm going to add the fix for my particular issue (Spring Boot, JPA using Hibernate, SQL Server 2014) since it doesn't exactly match the other answers included here:

I had a foreign key, e.g. my_id = '12345', but the value in the referenced column was my_id = '12345 '. It had an extra space at the end which hibernate didn't like. I removed the space, fixed the part of my code that was allowing this extra space, and everything works fine.

Faced the same Issue. I had an assosciation between 2 beans. In bean A I had defined the variable type as Integer and in bean B I had defined the same variable as Long. I changed both of them to Integer. This solved my issue.

It is a problem in your update method. Just instance new User before you save changes and you will be fine. If you use mapping between DTO and Entity class, than do this before mapping.

I had this error also. I had User Object, trying to change his Location, Location was FK in User table. I solved this problem with

@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);
}  
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!