web-dev-qa-db-ja.com

Hibernate:「XからYに変更されたインスタンスの識別子」を修正する方法

org.hibernate.HibernateException: identifier of an instance 
of org.cometd.hibernate.User altered from 12 to 3

実際、私のuserテーブルは実際にその値を動的に変更する必要があります。myJavaアプリはマルチスレッドです。修正方法はありますか?

51
gennad

Userオブジェクトの主キー値をどこかで変更していますか?あなたはそれをするべきではありません。主キーのマッピングが正しいことを確認してください。

マッピングXMLファイルまたはマッピングアノテーションはどのように見えますか?

38
Juha Syrjälä

IDフィールドを変更する前に、セッションからエンティティをデタッチする必要があります

26
Danubian Sailor

私の場合、hbm.xmlのPKフィールドは「整数」型でしたが、Beanコードではlongでした。

16
Muhammad Hewedy

私の場合、@ IdフィールドタイプをlongからLongに変更して解決しました。

4
Andres

私の場合、ゲッターとセッターの名前は変数名とは異なりました。

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

私の特定のケースでは、これはサービスの実装でspring @Transactional(readOnly = true)注釈を必要としたメソッドが原因でした。それを追加すると、問題は解決しました。珍しいことですが、それは単なる選択ステートメントでした。

3
Ethereal

私の場合、テンプレートにはタイプミスがあったため、等価性(==)をチェックする代わりに、割り当てイコール(=)を使用していました。

そこで、テンプレートロジックを次のように変更しました。

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

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

そして今、すべてが大丈夫です。だから、あなたの意見もチェックしてください!

3
nostromo

私もこの問題に直面していました。

ターゲットテーブルはリレーションテーブルで、異なるテーブルの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のヒントをありがとう、私はちょうどそれを逃しました。

2
bully

問題はさまざまなタイプのオブジェクトのPK(この場合は「ユーザー」)にあり、session.get(type, id);を取得するように休止状態を要求することもできます。

私の場合、エラーはidentifier of an instance of <skipped> was altered from 16 to 32。オブジェクトのPKタイプはIntegerで、hibernateはLongタイプを要求されました。

1

これは古い質問ですが、ここに含まれる他の回答と正確に一致しないため、特定の問題(Spring Boot、Hibernateを使用したJPA、SQL Server 2014)の修正を追加します。

外部キーがありました。 my_id = '12345'ですが、参照列の値はmy_id = '12345'でした。ハイバネートが気に入らなかったextra spaceが最後にありました。スペースを削除し、この余分なスペースを許可していたコードの一部を修正しましたが、すべて正常に動作します。

0
Erik Pearson

同じ問題に直面しました。 2つのBeanの間の関連付けがありました。 Bean Aでは変数型をIntegerとして定義し、Bean Bでは同じ変数をLongとして定義しました。両方を整数に変更しました。これで問題が解決しました。

0
HARSH KHATRI

更新方法に問題があります。変更を保存する前に新しいユーザーをインスタンス化するだけで問題ありません。 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);
}  
0
I.R.1989

Spring MVCまたはSpring Bootを使用している場合は、避けるようにしてください:@ ModelAttribute( "user")あるcontroolerと他のコントローラーでmodel.addAttribute( "user"、userRepository.findOne (someId);

この状況では、このようなエラーが発生する可能性があります。

0
sereja

私の場合、プロパティはオブジェクトでは長いがマッピングxmlではintだったため、この例外はより明確になるはずです

0
KgaboL