0

Spring 3.2 と hibernate-core 4.1.4 と hibernate-jpa-2.0.1 を使用しています。アプリケーション リソース ファイルには、正しいオブジェクトがすべて含まれています。

子オブジェクト RoleEntity があり、それには User と Award の 2 つの親があるため、userId と awardId は既に存在する外部キーであり、役割エンティティを作成するには存在しなければなりません。

public class RoleEntity implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "role_id")
    private long roleId;

    @Column(name = "role_description")
    private String roleDescription;

    @Column(name = "role_name")
    private String roleName;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private UserEntity user;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "award_id")
    private AwardEntity award;

     ... getters/setters
     ... hash/equals/toString
}

私のDAO挿入は非常に単純に見えます:

@Override
public RoleEntity saveRoleEntity(RoleEntity role)
{
     logger.debug("saveRoleEntity: role=" + role);
     return role;
}

このコードの単体テストを行ったところ、既存の roleId を選択すると、User と Award が完全に取り込まれた状態で、読み込まれたオブジェクトを完全に取得できることが確認できました。

ただし、新しいロールを挿入するときは、次のようにします。

  1. roleId を 0 に設定し、役割の説明を ...
  2. userEntity を作成し、ID のみを設定します。この ID は既に存在し、新しいものではありません
  3. awardEntity を作成し、ID のみを設定します。この ID は既に存在し、新しいものではありません

私はセーブを成功させることができ、これは素晴らしいです!!!! 私のために働きます。そして、新しいオブジェクトの戻り値では、新しい roleId が返されていることがはっきりとわかります!!! 説明など、RoleEntity の他のすべてのフィールドがあります。

しかし、私が望んでいるのは、RoleEntity の User フィールドと Award フィールドが、挿入後に選択したかのように完全に入力されることです。これは可能ですか?

これらのオブジェクトを取得してからこのオブジェクトに割り当てるために、ユーザーテーブルとアワードテーブルを選択しないことをお勧めしますが、それを行う必要がある場合は問題ありません。

さらに情報を提供する必要がある場合は、お知らせください。事前に助けてくれてありがとう。

4

2 に答える 2

1

このアプローチを試してください:

sess.save(role);
sess.flush(); //force the SQL INSERT
sess.refresh(role);

于 2013-02-01T21:55:52.050 に答える
0

ここで2つのこと。まず第一に、この ID を使用するためだけに、既知の ID を持つ新しいエンティティを作成しないでください。このアプローチは、発生するのを待っている事故です。この ID を持つエンティティは既に存在し、この重複キーのためにConstraintViolationExceptionorに遭遇します。NonUniqueObjectException

Hibernateでは、既知の ID を持つエンティティを使用したいが、データベースから完全なエンティティを選択したくない場合にプロキシを使用できます。

UserEntity user = session.load(UserEntity.class, userId);
AwardEntity award = session.load(AwardEntity.class, awardId);

これはエンティティを選択するためにデータベースにヒットしませんが、プロキシ (既知の ID をラップする) が返されます。同じセッション内で、完全なエンティティのようにプロキシを使用して新しいエンティティを作成できますRoleEntity

RoleEntity role = new RoleEntity();
role.setUser(user);
role.setAward(award);
session.save(role);

2 つ目は、Hibernateがエンティティの ID 以外のプロパティをデータベースにアクセスせずに知るにはどうすればよいでしょうか!? Hibernate がこれを行う唯一の方法は、Second Level Cache (L2C) を使用することですが、あなたの質問から、L2C が配置されていないと思います。

@ManyToOneアソシエーションがeager-fetchedであっても、Hibernateはデータベースにヒットして、それに応じたエンティティを設定する必要があります。したがって、@ Bogdan の回答のアプローチを使用して、挿入後にロールと関連するユーザーおよび賞のエンティティを再読み込みできます。

session.save(role);
session.refresh(role);

ただし、これには、新しいロールに割り当てるために最初に適切なエンティティを選択するよりもパフォーマンス上の利点はありません

UserEntity user = session.get(UserEntity.class, userId);
AwardEntity award = session.get(AwardEntity.class, awardId);    

これはすぐにデータベースにヒットし、エンティティにデータを入力します (または、指定された ID を持つ行が存在しない場合は null を返します)。

プロキシを使用している場合、同じセッション内でオンデマンドでエンティティを設定できることに注意してください。ID 以外のプロパティにアクセスするとすぐに、対応するエンティティがデータベースから選択されます。

とはいえ、理解を深めるために Hibernate のドキュメントを参照することをお勧めします。プロダクション レベルで Hibernate を使用する場合は、Java Persistence with Hibernateなどの優れた Hibernate の本も読む必要があります。

お役に立てれば。

于 2013-02-02T11:28:15.683 に答える