fru*_*ose 8 java hibernate jpa map playframework
我最近开始玩Play!Java的框架,版本1.2.3(最新版本).在测试框架时,我遇到了一个奇怪的问题,试图将一个Map对象保存在一个名为Hibernate的实体中FooSystem.地图对象映射长到Hibernate的实体,我呼吁Foo,随着申报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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是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();
}
}
Run Code Online (Sandbox Code Playgroud)
表演!框架自动为HTTP请求创建了一个事务.虽然数据插入foo和foosystem表格,不会将任何东西插入到foomap表,这是理想的结果.我该怎么办?我错过了什么?
我设法使用 Java Ka Baby 的建议解决了这个问题。这个问题实际上不在我的Model课堂上;问题出在Controller. 具体来说,我以错误的顺序保存实体。一旦我意识到在 上使用@ElementCollection注释Map<Long, Foo>产生了与我手动指定的连接表相同的效果,我尝试了我的思想实验,我重新思考了如何保存我的实体。
在我上面发布的代码中,您可以在FooSystem构造函数中看到在持久化对象之前放入了两个Foo对象f1和。我意识到如果它在放入地图时不在数据库中,那么JPA如何能够将其ID用作连接表中的外键?f2fooMapFoof1
如果您能看到我的推理思路,您会发现显而易见的答案是 JPA无法完成使用外键引用不存在的键的惊人壮举。奇怪的是,播放!控制台根本没有注意到我发布的原始代码有任何错误,即使它根本不正确。要么框架吞下了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();
}
}
Run Code Online (Sandbox Code Playgroud)
而且,由于我更改了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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13484 次 |
| 最近记录: |