2017-08-30 15 views
1

私はあなたに説明的な例を与えて自分自身を説明します。のは、次のようにコード化された私たちはJPAを使用して、非常に単純なクラウドストレージをプログラミングしているので、我々は2つの主なクラスがあり、UserFile言ってみましょう:JPA:この地図コレクションにはどのように注釈を付ける必要がありますか?

class User { 
     List<File> ownFiles; 
     Map<File, Integer> sharedFiles; 
} 

class File { 
     User author; 
     Map<User, Integer> sharedUsers; 
} 

どのように私は、このフィールドに注釈を付ける必要がありますか?私は試しましたが、私はいつもNotSerializableException"データが長すぎます"を取得します。ところで

  • は、Fileは一例であり、私の本当のクラスが小さい、唯一のいくつかの文字列で構成。だから私はかなりマップの注釈のためにNotSerializableExceptionがスローされていると確信しています。ところで

  • 、ここにあなたがUserの場合は地図値の意味、

    • を持っている、ファイルの整数値は、ファイルを介してユーザの権限レベルを表している
    • そしてFileの場合、キーは、ファイルがに共有されているそれらのユーザーであり、値がFile
超えるそのユーザーの権限レベルです

PS:地図<>ようにJPA 1.0によって処理することができないコメントで述べたように、私はEclipseLinkを

+1

NotSerializableExceptionは、注釈を付けていないと、デフォルトのマッピングになり、オブジェクトをシリアライズしようとするからです。コレクションの使い方を教えてくれるわけではありません。コレクションの使い方、整数値の格納場所、格納場所などを教えてください。JPAチュートリアルManyToManyマッピング。 – Chris

+0

おそらくエンジンは、このフィールドを「残酷な」非リレーショナルな方法(BLOB/CLOBなど)で保存したいので、直列化しようとします。オブジェクト・リレーショナルな方法でJPAにマップを格納することはできません。再設計を提案する、JPAでのプロジェクトは、古典的なOOPと必ずしも一致しないルールを維持しなければならない。つまり、マップは悪い。 –

+0

は、ファイルに異なるクラス名を使用することをお勧めします –

答えて

0

を考えてみましょう私は、次のようにフィールドを注釈されている:

class User { 
     @OneToMany 
     List<File> ownFiles; 

     @ElementCollection 
     Map<File, Integer> sharedFiles; 
} 

class File { 
     @ManyToOne 
     User author; 

     @ElementCollection 
     Map<User, Integer> sharedUsers; 
} 

より詳細:

class User { 
     @OneToMany 
     @JoinTable(name = "USER_HAS__OWN_FILES", joinColumns = { 
     @JoinColumn(name = "AUTHOR", referencedColumnName = "USERNAME")}, 
      inverseJoinColumns = {@JoinColumn(name = "OWN_FILE_ID", referencedColumnName = "ID") }) 
     List<File> ownFiles; 

     @ElementCollection 
     @CollectionTable(name = "USER_HAS_SHARED_FILES", joinColumns = 
     @JoinColumn(name = "USERNAME", referencedColumnName = "USERNAME")) 
     @MapKeyJoinColumn(name = "SHARED_FILE_ID", referencedColumnName = "ID") 
     @Column(name = "PERMISSION_LEVEL") 
     Map<File, Integer> sharedFiles; 
} 

class File { 
     @ManyToOne 
     @JoinColumn(name = "FILE_AUTHOR", referencedColumnName = "USERNAME") 
     User author; 

     @ElementCollection 
     @CollectionTable(name = "FILE_HAS_BEEN_SHARED_TO_USER", 
      joinColumns = @JoinColumn(name = "FILE_ID", referencedColumnName = "ID")) 
     @MapKeyJoinColumn(name = "USER_THAT_FILE_HAS_BEEN_SHARED_TO", referencedColumnName = "USERNAME") 
     @Column(name = "PERMISSION_LEVEL") 
     Map<User, Integer> sharedUsers; 
} 

が今では、次のトンを生成し、私が期待どおりに動作ABLES:

  • User (ID, Username, ...)
  • File (ID, Filename, Author, ...)
  • User_has_shared_files (Username, Shared_file_id, permission_level)
  • User_has__own_files (Username, Own_file_id)
  • File_has_been_shared_to_user (File_id, Username_id, permission_level)

@ElementCollection注釈は、マップするために便利ですJava.Map<Entity, basicType>

+0

私はちょうどUser_has_shared_filesとFile_has_been_shared_to_userが等価であるので、データがデータベースに2回保存されるということを理解しました – Maximetinu

1

を使用してい

JPA 2.0は多くて、注釈を追加しました(そう起こるシリアライズしようとすると)データベースは、私の意見では

simmilarすることができ、生成繊細な属性(個人的な意見) https://wiki.eclipse.org/EclipseLink/Examples/JPA/2.0/ElementCollections 複雑quirts、私は驚いていないよ私はJPとデータベースより良好な制御を持っています1つの方法(私のためにきれいです)。私の提案を見せてください。

1.xの哲学であなたの論理構造の私のクリアがあるのです:

class User { 
    // ... fields waht You want 
} 

class FileEtiquette { 
     User author; 
} 

class SharingIncident { 
    User user; 
    FileEtiquette file; 
    int level; 
} 

たぶん私は名前はエレガントではないことができるようにし、完全にあなたの命名法を理解しません。

次の試みは、コンパイルされていません。

@Entity 
    class User { 
     @Id 
     int id; 
     @Basic 
     Set<SharingIncident> shares; 
     @Basic 
     Set<FileEtiquette> myFiles; 
     // ... fields waht You want 
    } 

@Entity 
class FileEtiquette { 
    @Id 
    int id; 
    @Basic 
    Set<SharingIncident> sharedBy; 
    User author; 
} 

@Entity 
class SharingIncident { 
    @Id 
    int id; 
    User user; 
    FileEtiquette file; 
    int level; 
} 

ごくわずかです。

  • 多くするために、多くは「自動的」な方法で実現しますが、あなたの 例の整数フィールドに手動で関係 を設計する価値が、面白いですすることができます。通常
  • 平均プログラマはList<>を考えて、JPA Set<>に あなたFile名を変更
  • 改善することができますそれはあなたの意思の私の理解に基づいて、可能な多くの改善だけで基礎である私の個人的な好み
  • です。私の目標は、可能な

次のステップの古典的な方法で>地図<置き換える方法を示すために、私はthis tutorialに基づいた瞬間に

+0

あなたのソリューションは適切に動作すると確信していますが、現在はJPA 2.1でMapを使用して解決したいと考えています。最終的に私があなたの提案を使用し終えると、私はあなたの答えを最良のものとしてマークします。ありがとう! – Maximetinu

関連する問題