13

Play で JPA を使用して HashMap を保存する方法について、ほぼ 1 週間苦労しています。他のすべての属性は格納されますが、HashMap だけに要素がありません (空です)。

public class ImageModel extends Model {

 @Id
 private String id;
 private String url;

 @ElementCollection(targetClass = java.lang.String.class)
 @MapKeyClass(java.lang.String.class)
 private Map<String,String> tags = new HashMap<>();

 // the method for adding keys and values to the HashMap
 public void add(String key, String value){
    tags.put(key,value);
    this.save();
}

}

私も注釈を付けようとしました:

@ElementCollection(fetch=FetchType.LAZY)

したがって、今のところ私の唯一の推測は、Play を適切に構成していないということです。(私は Play2 を使用しており、データベース設定の前にある "#" (コメント マーク) を削除する以外は何も構成していないと言わざるを得ません)。

On Play のドキュメントには、「 Play 2.0 には組み込みの JPA 実装はありません」と記載されています。そうなのだろうか?

更新: 私はいくつかの調査を行い、Play - H2 のデフォルト データベースを使用していることが原因である可能性があると述べました。私はMySQLで試しました-ビデオのやり方ですが、ここでもIDとURLのみが保存されます。クラスの名前を持つMySQLデータベースとテーブルを調べましたが、2つの属性(idとurl)しかなく、HashMapの痕跡はありませんでした。

Update2 : 印刷画面を追加 - データベース クエリを使用。

Update3 : Play のサンプル "computer-database-jpa" は正常に動作しているため、JPA は問題ないはずですが、そのサンプルでは Map (HashMap) が使用されていませんでした。EclipseLinkで休止状態を変更しましたが、まだ機能していません。:( (ただし、すべての基本型属性はデータベースにあります)

4

2 に答える 2

4

モデルを使用して HashMap を実装する方法は次のとおりです。

@Entity
public class ImageModel extends Model {
    //All your fields, etc.

    @ManyToMany(mappedBy = "imagesWithTag")
    @MapKey(name = "name")
    public Map<String,Tag> tags = new HashMap<String,Tag>();
}

@Entity
public class Tag extends Model {
    // All your fields, etc.

    public String name;
    public String value;

    @ManyToMany
    public List<ImageModel> imagesWithTag = new ArrayList<ImageModel>();
}

クエリを簡単に作成できるように、Tag のモデル全体を作成するという Eric の提案に従うことにしましたが、Map の機能を使用できると非常に役立つ場合があります。これは EnumMaps でも機能するはずです。

public void addTag(String tagName, String value) {
    Tag tag = Tag.finderTag.where().eq("name", tagName).eq("value", value).findUnique();
    if(tag == null) {
        tag = Tag.newTag(tagName, value);
    }
    this.tags.put(tag.name, tag);
    this.saveManyToManyAssociations("tags");
}

public static List<ImageModel> getImagesWithTag(String tagName, String tagValue) {

    Tag tag = finderTag.where().eq("name", tagName).eq("value", tagValue).findUnique();

    List<ImageModel> images = new ArrayList<ImageModel>();
    for(ImageModel model : tag.imagesWithTag) {
        images.add(model);
    }
    return images;
}

私は Play Framework モデルでマップを使用することについてほとんど何も見たことがなかったので、小さなサンプル プロジェクト (Play 2.1.1) を作成して、マップの使用法をいじり、さらにデモンストレーションすることにしました。

https://github.com/Raymond26/play-framework-demos/tree/master/PlayMap

于 2013-07-12T18:36:22.163 に答える
1


ここでの本当の問題は、これらのタグをマップに保存する理由だと思います。、 などのkey->valueペアになると思いますよね? "author"->"John Smith""theme"->"Animals"

私見、タイプが必要ですTag

@Entity
class Tag {
    @Id
    private Long id;
    private String name;
    private String value;
    // getters, setters, hashCode, equals, etc.
    // ...
}

と関係がありImageModelます:

public class ImageModel extends Model {
    // ...
    @ManyToMany
    private Set<Tag> tags;
    // ...
}

ここには、関係が何であるかを本当に明示する強力な型付きコレクションがあります。

Tagこのようにして、一意の制約、いくつかの検証 (JSR303)、追加フィールド、Javadoc、単体テストなどの興味深いものを追加できます。

また、これにより、次のような便利なクエリを簡単に実行できます。

  • タグで画像を探す
  • 既存のタグを一覧表示する
  • 「作者」という名前のタグを一覧表示する
  • ...
于 2013-06-02T09:23:06.697 に答える