Hibernate:「XからYに変更されたインスタンスの識別子」を修正する方法は?
-
10-10-2019 - |
質問
org.hibernate.HibernateException: identifier of an instance
of org.cometd.hibernate.User altered from 12 to 3
実際、私 user
テーブルは実際にその値を動的に変更する必要があり、Javaアプリはマルチスレッドです。それを修正する方法はありますか?
解決
どこかでユーザーオブジェクトの主要なキー値を変更していますか?あなたはそれをするべきではありません。主キーのマッピングが正しいことを確認してください。
マッピングXMLファイルまたはマッピングアノテーションはどのようになりますか?
他のヒント
IDフィールドを変更する前に、エンティティをセッションから取り外す必要があります
私の場合、hbm.xmlのPKフィールドはタイプ「整数」でしたが、Beanコードでは long
.
私の場合、@IDフィールドのタイプを長く長に変えることを解決しました。
私の場合、ゲッターとセッター名は変数名とは異なりました。
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;
}
私の特定のケースでは、これは私のサービス実装の方法がスプリングを必要とする方法によって引き起こされました @Transactional(readOnly = true)
注釈。それを追加すると、問題は解決されました。珍しいことに、それは単なる選択的なステートメントでした。
私の場合、テンプレートにはタイプミスがあったため、同等性(==)をチェックする代わりに、割り当て等(=)を使用していました。
そこで、テンプレートロジックを次のように変更しました。
if (user1.id = user2.id) ...
に
if (user1.id == user2.id) ...
そして今、すべては大丈夫です。だから、あなたの意見も確認してください!
IDを変更しながら、同じユーザーオブジェクトを複数回使用しようとしていないことを確認してください。言い換えれば、バッチタイプの操作で何かをしている場合:
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);
}
私もこの問題に直面していました。
ターゲットテーブルは関係テーブルで、異なるテーブルから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
@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
, 、冬眠が求められました Long
タイプ。
私の場合、それはプロパティがオブジェクト上で長いが、マッピングXMLのINTであったため、この例外はより明確でなければなりません
スプリングMVCまたはスプリングブーツを使用している場合は、避けてください。@modelattribute( "user") 1つのコントラー、および他のコントローラーでModel.Addattribute( "user"、userrepository.findone(someid);
この状況はそのようなエラーを生成する可能性があります。
これは古い質問ですが、特定の問題の修正(Spring Boot、Hibernate、SQL Server 2014を使用したJPA)の修正を追加します。
Eg_id = '12345'などの外部キーがありましたが、参照列の値はmy_id = '12345'でした。それはありました 余分なスペース 最後に、冬眠が好きではなかった。スペースを削除し、この余分なスペースを可能にするコードの一部を修正しました。すべてが正常に機能します。
同じ問題に直面しました。私は2豆の間の関連性を持っていました。 Beanでは、AIは変数タイプを整数として定義しており、Bean BIは同じ変数を長いと定義していました。両方を整数に変更しました。これは私の問題を解決しました。
更新方法の問題です。変更を保存する前に新しいユーザーをインスタンスするだけで、大丈夫です。 DTOクラスとエンティティクラス間のマッピングを使用する場合、マッピング前にこれを行うよりも。
このエラーもありました。私は彼の場所を変更しようとしているユーザーオブジェクトを持っていました、場所はユーザーテーブルの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);
}
オブジェクトに依存する新しいインスタンスをインストールすることで、これを解決します。例として
instanceA.setInstanceB(new InstanceB());
instanceA.setInstanceB(YOUR NEW VALUE);