Ответ 1
Вы меняете значение первичного ключа для объекта User где-то? Вы не должны этого делать. Убедитесь, что правильное отображение для первичного ключа.
Как выглядит ваше сопоставление XML файла или аннотации сопоставления?
org.hibernate.HibernateException: identifier of an instance
of org.cometd.hibernate.User altered from 12 to 3
на самом деле, моя таблица user
действительно должна динамически изменять ее значение, мое приложение Java многопоточно.
Есть идеи, как это исправить?
Вы меняете значение первичного ключа для объекта User где-то? Вы не должны этого делать. Убедитесь, что правильное отображение для первичного ключа.
Как выглядит ваше сопоставление XML файла или аннотации сопоставления?
Вы должны отделить свою сущность от сеанса до изменения ее полей идентификатора
В моем случае поле PK в файле hbm.xml имело тип "integer", но в коде bean оно было long
.
В моем случае я решил, что он меняет тип поля @Id от long до Long.
В моем конкретном случае это было вызвано методом в моей реализации службы, который нуждался в аннотации spring @Transactional(readOnly = true)
. Как только я добавил, проблема была решена. Необычно, но это был просто оператор select.
В моем случае шаблон имел опечатку, поэтому вместо проверки эквивалентности (==) он использовал присваивание равно (=).
Итак, я изменил логику шаблона:
if (user1.id = user2.id) ...
to
if (user1.id == user2.id) ...
и теперь все в порядке. Итак, проверьте свои взгляды!
В моем случае имена getters и 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;
}
Убедитесь, что вы не пытаетесь использовать один и тот же объект пользователя несколько раз при изменении идентификатора. Другими словами, если вы делали что-то в операции типа пакета:
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);
}
Я тоже столкнулся с этой проблемой.
Таблица целей - таблица отношений, проводящая два идентификатора из разных таблиц. У меня есть УНИКАЛЬНОЕ ограничение на комбинацию значений, заменяя ПК. При обновлении одного из значений кортежа эта ошибка возникла.
Вот как выглядит таблица (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)
);
Класс Entity для объекта 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 ( "Пользователь" в вашем случае) и введите, что вы запрашиваете hibernate для получения session.get(type, id);
.
В моем случае ошибка была identifier of an instance of <skipped> was altered from 16 to 32
.
Тип объекта PK был Integer
, для спящего режима был задан тип Long
.
В моем случае это было потому, что свойство было длинным на объекте, но int в сопоставлении xml, это исключение должно быть более ясным
Если вы используете 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 определен тип переменной как Integer, а в bean BI определена та же переменная, что и в Long. Я изменил их обоих на Integer. Это решило мою проблему.
Это проблема в вашем методе обновления. Просто сохраните изменения, прежде чем сохранить изменения, и все будет в порядке. Если вы используете отображение между 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);
}