Remove() メソッドによる削除

最後に、オブジェクトの削除を見てみましょう。原則として、データベースからオブジェクトを削除するのは非常に簡単ですが、言われているように、微妙な違いがあります。そして、そのようなニュアンスは6つあります。

  • Remove()メソッドによる削除
  • 会社側の削除
  • 孤立者による削除
  • JPQLで削除する
  • NativeQueryによる削除
  • ソフト削除()

そして、最も明白な解決策である、remove()メソッドの呼び出しから始めます。

User user = new User();
user.setName("Kolyan");
session.persist(user);  // add an object to the database
session.flush();
session.clear();  // close the session

user = (User) session.find(User.class, user.getId() ); //receive the object from the database
session.remove(user);
session.flush();
session.clear();  // close the session

//here the object is actually deleted.

データベース内の実際の操作は、flush()メソッドが呼び出されるか、トランザクションが閉じられた後に実行されます。

カスケード削除

私たちが SQL を勉強したとき、依存テーブルは CONSTRAINT を使用して作成できたことを覚えていますか。そしてそのうちの1つは次のようになりました。

CONSTRAINT ONDELETE REMOVE

その意味は、子エンティティを含むテーブルがある場合、親エンティティが割り当てられたときに、そのすべての子を削除する必要があるということでした。

ユーザーの個人情報をどこかに保存し、ユーザーが削除されるとこのデータも削除されるようにデータベースに CONSTRAINT を設定するとします。次に、親オブジェクトを削除するだけで、すべての子オブジェクトが基本レベルで削除されます。

User user = new User();
UserPrivateInfo info = new UserPrivateInfo();
user.setPrivateInfo(info);
session.persist(user);  //add the object to the database, the info object will also be saved to the database
session.flush();
session.clear();  // close the session

user = (User) session.find(User.class, user.getId() ); //receive the object from the database
session.remove(user);
session.flush();
session.clear();  // close the session

// here the user and info objects are actually removed from the database.

孤立者による削除

オーファン除去と呼ばれる別のタイプの除去もあります。以前のバージョンと多少似ています。子エンティティは、親エンティティとの関係が壊れると削除されます。この場合、通常、親エンティティは削除されません。

ユーザーがいて、彼が投稿のリストを持っているとします。

User user = new User();
UserMessage message = new UserMessage();
user.getMessageList().add(message);
session.persist(user);  //add the object to the database, the message object will also be saved to the database
session.flush();
session.clear();  // close the session

user = (User) session.find(User.class, user.getId() ); //receive the object from the database
UserMessage message2 = user.getMessageList().get(0); //get the user's message
user.getMessageList().remove(message2);  //remove the message from the list
session.flush();
session.clear();  // close the session

// here the message2 object is actually removed from the database

また、重要なニュアンスがあります。Hibernate にこの動作を実装させたい場合は、アノテーションを使用して 2 つのエンティティをリンクするときに明示的に指定する必要があります。

@Entity
public class User {

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<UserMessage> messageList = new ArrayList<UserMessage>();

}

JPQL経由で削除

オブジェクトを削除するもう 1 つの興味深い方法は、HQL (または JPQL) クエリを作成することです。最後にexecuteUpdate()メソッドを呼び出すことを忘れないでください。そうしないと、Hibernateは読み取り専用トランザクションを作成し、削除されません。

例:

User user = new User();
session.persist(user);  // add an object to the database
session.flush();
session.clear();  // close the session

session.createQuery("delete from User where id = :id")
   .setParameter("id", user.getId())
   .executeUpdate();

データベースを変更しても、既存の Entity オブジェクトは一切変更されません。

NativeQueryによる削除

同様に、NativeQuery を削除して呼び出すことができます。

例:

User user = new User();
session.persist(user);  // add an object to the database
session.flush();
session.clear();  // close the session

session.createNativeQuery("DELETE FROM user WHERE id = :id")
   .setParameter("id", user.getId())
   .executeUpdate();

データベースの変更は、既存の Entity オブジェクトにはまったく影響しません。

論理的な削除

場合によっては、データベース内のデータを削除する代わりに、単純に削除済みとしてマークしておくと便利です。このようなデータは、さまざまなシナリオに参加できます。まず、このような削除は簡単に元に戻すことができ、ラインを再びライブとしてマークすることができます。

次に、サーバーの動作が法律などで規制されている場合があるため、このようなリモートデータを「アーカイブ」すると便利です。ただし、データを削除済みとしてマークすると、そのデータが削除されたことを知ることができるのは自分だけです。Hibernate は引き続きこのデータを検索し、並べ替えの際にも使用します。

したがって、Hibernate の作成者は、オブジェクトを生きているものとしてマークできる特別なアノテーションを考案しました。例:

@Entity
@Where(clause = "DELETED = 0") //in all WHEREs "AND DELETED = 0" will be added
public class User {
	// mapping fields

	@Column(name = "DELETED") // if the value in the DELETED column == 0, then the record is alive, if 1 - dead
	private Integer deleted = 0;

	//getters and setters

    public void softDeleted() {
    	this.deleted = 1; //mark the post as dead
    }
}

オブジェクトを削除済みとしてマークするには、そのオブジェクトに対してSoftDeleted()メソッドを呼び出すだけです。

User user = new User();
session.persist(user);  // add an object to the database
session.flush();
session.clear();  // close the session

user = (User) session.find(User.class, user.getId() ); //receive the object from the database
user.softDeleted(); // mark the object as deleted
session.flush();
session.clear();  // close the session

//this object will no longer reside via Hibernate