【问题标题】:Play Framework: Solution for storing a Map, key - value using JPAPlay Framework:使用JPA存储Map、key-value的解决方案
【发布时间】:2013-05-29 15:33:14
【问题描述】:

我为如何在 Play 中使用 JPA 存储 HashMap 苦苦挣扎了将近一周。存储了所有其他属性,只有 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 - video how to do it ,但它再次只保存 id 和 url。我查看了 MySQL 数据库和表,类名只有 2 个属性(id 和 url),没有我的 HashMap 的痕迹。

Update2:添加了打印屏幕 - with database query.

Update3:来自 Play 的示例“computer-database-jpa”工作正常,因此 JPA 应该没问题,但该示例没有使用 Map (HashMap)。我什至用 EclipseLink 更改了休眠模式,但仍然无法正常工作。 :((尽管所有基本类型属性都在数据库中)

【问题讨论】:

  • 你在play框架文件夹中看到提供的示例项目(computer-database-jpa)来验证配置。
  • 我从 java 文件夹中测试了 computer-database-jpa 并且工作正常。
  • 我认为这与 Play Framework 没有任何关系。保存了其他属性,因此持久性正在工作。你应该修改你的问题的标题和标签,你会有更多的答案。

标签: jakarta-ee jpa playframework playframework-2.0


【解决方案1】:

这是我使用您的模型实现 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>();
}

我决定接受 Eric 的建议,即为 Tag 创建一个完整的模型,以便轻松进行查询,但有时能够使用 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

【讨论】:

  • 感谢您的回复以及来自 github 的整个示例。我由衷的感谢。
【解决方案2】:

我认为这里真正的问题是:
为什么将这些标签存储在地图中?我想这将是某种key-&gt;value 对,例如"author"-&gt;"John Smith""theme"-&gt;"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、单元测试等。

此外,这让您可以轻松地进行一些有用的查询,例如:

  • 按标签搜索图片
  • 列出现有标签
  • 列出名称为“作者”的标签
  • ...

【讨论】:

    猜你喜欢
    • 2019-02-01
    • 2013-04-11
    • 2014-02-11
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 2021-09-05
    相关资源
    最近更新 更多