【问题标题】:How do I use JPA to persist a Map (java.util.Map) object inside an entity and ensure the persistence cascades?如何使用 JPA 在实体内持久化 Map (java.util.Map) 对象并确保持久性级联?
【发布时间】:2011-11-23 04:30:20
【问题描述】:

我最近开始玩 Play! Java 框架,版本 1.2.3(最新)。在测试框架时,我在尝试在名为 FooSystem 的 Hibernate 实体中保留 Map 对象时遇到了一个奇怪的问题。 Map 对象将 long 映射到我称为 Foo 的 Hibernate 实体,声明为 Map<Long, Foo> fooMap;

我的问题如下:创建了正确的表,因为我已经注释了它们。但是,当FooSystem对象fs被持久化后,fs.fooMap中的数据就没有了!

这是我用于实体的代码。首先是Foo

package models.test;

import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import play.db.jpa.Model;

@Entity
public class Foo extends Model
{
    @ManyToOne
    private FooSystem foosystem;

    public Foo(FooSystem foosystem)
    {
        this.foosystem = foosystem;
    }
}

这里是FooSystem:

package models.test;

import java.util.HashMap;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import play.db.jpa.Model;

@Entity
public class FooSystem extends Model
{
    @ManyToMany(cascade = {CascadeType.ALL, CascadeType.PERSIST})
    @JoinTable(
        name = "fooMap",
        joinColumns = @JoinColumn(name = "foosystem"),
        inverseJoinColumns = @JoinColumn(name = "foo")
    )
    private Map<Long, Foo> fooMap = new HashMap<Long, Foo>();

    public FooSystem()
    {
        Foo f1 = new Foo(this);
        Foo f2 = new Foo(this);
        fooMap.put(f1.getId(), f1);
        fooMap.put(f2.getId(), f2);
    }

    public Map<Long, Foo> getFooMap()
    {
        return fooMap;
    }
}

这是我用来测试我的设置的Controller 类:

package controllers;

import javax.persistence.EntityManager;
import models.test.FooSystem;
import play.db.jpa.JPA;
import play.mvc.Controller;

public class TestController extends Controller
{
    public static void index() {
        EntityManager em = JPA.em();
        FooSystem fs = new FooSystem();
        em.persist(fs);
        render();
    }
}

戏剧!框架自动为 HTTP 请求创建了一个事务。尽管数据被插入到foofoosystem 表中,但没有任何东西被插入到foomap 表中,这是期望的结果。我能做些什么呢?我错过了什么?

【问题讨论】:

  • 您使用的是什么版本的 JPA。JPA2 有 '@ElementCollection' 执行此操作 download.oracle.com/javaee/6/api/javax/persistence/…
  • 事实上,我正在使用 JPA2。我尝试了您的建议,在对保存实体的顺序进行了一些调整后,它起作用了!我将在接下来的 24 小时内发布完整的解决方案!我住的地方已经很晚了,我需要睡觉。谢谢您的帮助!在搜索我的问题时,我在 Internet 其他地方看到了 @ElementCollection 注释,但是在我第一次尝试时使用 @ElementCollection 并没有工作。直到现在我才把它写下来。谢谢!

标签: java hibernate jpa map playframework


【解决方案1】:

我根据 Java Ka Baby 的建议设法解决了这个问题。这个问题实际上不在我的Model 课程中;问题在于Controller。具体来说,我以错误的顺序保存实体。当我意识到在Map&lt;Long, Foo&gt; 上使用@ElementCollection 注释产生的效果与我手动指定的连接表相同时,我尝试了我的思考实验,我重新思考了如何保存我的实体。

在我上面发布的代码中,您可以在FooSystem 构造函数中看到两个Foo 对象f1f2,在Foo 对象被持久化之前被放入fooMap。我意识到如果f1在放入映射时不在数据库中,JPA如何能够将其ID用作连接表中的外键?

如果您可以通过这条推理了解我的目标,您可以看到显而易见的答案是 JPA 无法 完成使用外键引用这一惊人壮举一个不存在的钥匙。奇怪的是,Play!控制台根本没有注意到我发布的原始代码有任何错误,即使它根本不正确。要么框架吞下过程中抛出的每个Exception,要么我编写了应该产生Exception的代码。

所以为了解决这个问题,我在对它们执行任何操作之前保留了 Foo 实体。直到那时我才将它们放入fooMap。最后,一旦fooMap 被填充,我就持久化了FooSystem 实体。

这是更正后的TestController 类:

package controllers;

import javax.persistence.EntityManager;
import models.test.Foo;
import models.test.FooSystem;
import play.db.jpa.JPA;
import play.mvc.Controller;

public class TestController extends Controller
{
    public static void index() {
        EntityManager em = JPA.em();
        FooSystem fs = new FooSystem();
        Foo f1 = new Foo(fs);
        Foo f2 = new Foo(fs);
        f1.save();
        f2.save();
        fs.put(f1.getId(), f1);
        fs.put(f2.getId(), f2);
        fs.save();
        render();
    }
}

而且,由于我更改了FooSystem,这是该类的最终代码:

package models.test;

import java.util.HashMap;
import java.util.Map;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import play.db.jpa.Model;

@Entity
public class FooSystem extends Model
{
    @ElementCollection
    private Map<Long, Foo> fooMap = new HashMap<Long, Foo>();

    public FooSystem()
    {
    }

    public Map<Long, Foo> getFooMap()
    {
        return fooMap;
    }

    public void put(Long l, Foo f)
    {
        fooMap.put(l, f);
    }
}

【讨论】:

    猜你喜欢
    • 2012-06-17
    • 2013-10-26
    • 2018-05-15
    • 2011-03-12
    • 2016-01-05
    • 2015-11-02
    • 2013-11-06
    • 2021-05-06
    • 1970-01-01
    相关资源
    最近更新 更多