org.hibernate.HibernateException: identifier of an instance
of org.cometd.hibernate.User altered from 12 to 3
実際、私のuser
テーブルは実際にその値を動的に変更する必要があります。myJavaアプリはマルチスレッドです。修正方法はありますか?
Userオブジェクトの主キー値をどこかで変更していますか?あなたはそれをするべきではありません。主キーのマッピングが正しいことを確認してください。
マッピングXMLファイルまたはマッピングアノテーションはどのように見えますか?
IDフィールドを変更する前に、セッションからエンティティをデタッチする必要があります
私の場合、hbm.xmlのPKフィールドは「整数」型でしたが、Beanコードではlong
でした。
私の場合、@ IdフィールドタイプをlongからLongに変更して解決しました。
私の場合、ゲッターとセッターの名前は変数名とは異なりました。
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;
}
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);
}
私の特定のケースでは、これはサービスの実装でspring @Transactional(readOnly = true)
注釈を必要としたメソッドが原因でした。それを追加すると、問題は解決しました。珍しいことですが、それは単なる選択ステートメントでした。
私の場合、テンプレートにはタイプミスがあったため、等価性(==)をチェックする代わりに、割り当てイコール(=)を使用していました。
そこで、テンプレートロジックを次のように変更しました。
if (user1.id = user2.id) ...
に
if (user1.id == user2.id) ...
そして今、すべてが大丈夫です。だから、あなたの意見もチェックしてください!
私もこの問題に直面していました。
ターゲットテーブルはリレーションテーブルで、異なるテーブルの2つのIDを結び付けます。値の組み合わせに一意の制約があり、PKを置き換えます。タプルの値の1つを更新すると、このエラーが発生しました。
これは、テーブルがどのように見えるかです(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のヒントをありがとう、私はちょうどそれを逃しました。
問題はさまざまなタイプのオブジェクトのPK(この場合は「ユーザー」)にあり、session.get(type, id);
を取得するように休止状態を要求することもできます。
私の場合、エラーはidentifier of an instance of <skipped> was altered from 16 to 32
。オブジェクトのPKタイプはInteger
で、hibernateはLong
タイプを要求されました。
これは古い質問ですが、ここに含まれる他の回答と正確に一致しないため、特定の問題(Spring Boot、Hibernateを使用したJPA、SQL Server 2014)の修正を追加します。
外部キーがありました。 my_id = '12345'ですが、参照列の値はmy_id = '12345'でした。ハイバネートが気に入らなかったextra spaceが最後にありました。スペースを削除し、この余分なスペースを許可していたコードの一部を修正しましたが、すべて正常に動作します。
同じ問題に直面しました。 2つのBeanの間の関連付けがありました。 Bean Aでは変数型をIntegerとして定義し、Bean Bでは同じ変数をLongとして定義しました。両方を整数に変更しました。これで問題が解決しました。
更新方法に問題があります。変更を保存する前に新しいユーザーをインスタンス化するだけで問題ありません。 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);
}
Spring MVCまたはSpring Bootを使用している場合は、避けるようにしてください:@ ModelAttribute( "user")あるcontroolerと他のコントローラーでmodel.addAttribute( "user"、userRepository.findOne (someId);
この状況では、このようなエラーが発生する可能性があります。
私の場合、プロパティはオブジェクトでは長いがマッピングxmlではintだったため、この例外はより明確になるはずです