2

JPA / Hibernateを使用しています。

フォルダーとファイルがあるとします。すべてのフォルダーには、より多くのフォルダーとファイルを含めることができます。すべてのファイルは、(親ではなく) ルート フォルダーが何であるかを認識しています。

@Entity
public class Folder{
    ...

    @OneToMany
    @JoinColumn("folder_id")
    private List<Folder> folders;

    @OneToMany
    @JoinColumn("file_id")
    private List<File> files;

    ...
}

@Entity
public class File {
    ...

    @ManyToOne
    private Folder rootFolder;

    ...
}

新しいファイルと新しいフォルダーを作成します。ファイルをフォルダに入れました。これで、ファイルはフォルダー「files」コレクションにあり、フォルダーはファイル「rootFolder」変数で参照されます。

これを永続化すると、「オブジェクトは保存されていない一時インスタンスを参照しています」または「フラッシュする前に一時インスタンスを保存します: entities.file.rootFolder -> entities.Category」(最初に永続化されるものによって異なります) を取得します。

これに注釈を付ける方法が必要なので、最初に何を保存しても機能します!? 他のエンティティを参照せずに最初のエンティティを挿入し、次に別のエンティティを挿入してから参照を挿入するようにプログラムで何らかの方法で回避できますが、ここでは必要ないと思います。

これを検索したのですが、@OneToMany に @ManyToOne を組み合わせたものしか見つかりませんでしたが、私の場合は使用できません。フォルダーは、それがルート フォルダーであるかどうかを認識すべきではありません。

チュートリアルに関するご意見やご指示をいただければ幸いです。

4

2 に答える 2

5

これらのマッピングまたは説明したシナリオに問題はありません。すべてが 1 つのトランザクション内で発生すると仮定すると、またはより正確には、その間にフラッシュが発生しないと仮定します。あなたが説明するエラーは、通常、トランザクションのコミット時に発生するフラッシュ時にのみ発生します。「フラッシュする前に一時インスタンスを保存してください」というエラーも表示されます。許可されていないのは、部分的に保存されたオブジェクト グラフをフラッシュすることです。フラッシュが発生する前にグラフ内のすべてのオブジェクトが保存されている限り、問題はありません。

あなたのコードに基づいて、Github で実際の例を作成しました。コードを参照したり、プロジェクトを複製して実行したりできます。

git clone git://github.com/zzantozz/testbed.git tmp
cd tmp/stackoverflow/14921963-hibernate-circular-reference
mvn -q compile exec:java -D exec.mainClass=com.foo.Main
于 2013-02-17T15:33:02.780 に答える
0

同じトランザクション内で両方のオブジェクトを保持する場合、コードは機能するはずです。

ただし、ファイルとフォルダーの関係では、所有者を誤ってマークしています。ほとんどの場合、多対 1 側がリレーションシップの所有者になります。したがって、正しい方法は次のようになります。

@Entity
public class File {
  @ManyToOne
  @JoinColumn(name = "folder_id") // this table has a foreign key
  private Folder rootFolder;
}

@Entity
public class Folder {
  @OneToMany(mappedBy = "rootFolder") // 'File' is the owner of this relationship
  private List<File> files;
}

同様に、 ではFolder、次のようにする必要があります。

@OneToMany 
private List<Folder> folders;

または、双方向の関係を使用することもできます。

@Entity
public class Folder {
  @ManyToOne
  private Folder parent;

  @OneToMany(mappedBy = "parent")
  private List<Folder> folders;

これが役立つことを願っています。

于 2013-02-17T15:36:39.287 に答える