Мне удалось решить эту проблему по совету Java Ka Baby. Проблема была на самом деле не в моих Model
классах; проблема лежала в пределах Controller
. В частности, я сохранял объекты в неправильном порядке. Как только я понял, что использование аннотации @ElementCollection
на Map<Long, Foo>
произвело те же эффекты, что и таблица соединения, которую я указывал вручную, я попытался провести эксперимент, в котором я переосмыслил, как сохранять свои сущности.
В приведенном выше коде вы можете видеть в конструкторе FooSystem
, что два Foo
объекта, f1
и f2
, помещаются в fooMap
до того, как объекты Foo
будут сохранены. Я понял, что если f1
нет в базе данных, когда он помещен в карту, как JPA может использовать свой идентификатор в качестве внешнего ключа в таблице соединения?
Если вы видите, куда я иду с этой линией рассуждений, вы можете увидеть, что очевидный ответ заключается в том, что 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();
}
}
И, так как я изменил 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);
}
}