我正在使用带有JPA的Google App Engine来实现一对多的双向关系。当我在家里的机器上调试和测试我的应用程序时,一切正常,但在我将它部署到App Engine之后,持久性似乎已经崩溃。
这是我的模型(为简单起见而剥离):
User.java:
@Entity
class User implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
@OneToMany(mappedBy = "owner",
cascade = CascadeType.ALL,
fetch = FetchType.EAGER)
private List<Book> books;
public getBooks() { return this.books; }
}
Book.java:
@Entity
class Book implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
@ManyToOne(fetch = FetchType.LAZY)
private User owner;
private String name;
}
创建新的User
:
User user = new User()
// This is done just for testing. It works fine.
user.getBooks().add(new Book("TEST"))
EntityManager em = /* ... */
EntityTransaction transaction = em.getTransaction();
try
{
transaction.begin();
em.persist(user);
transaction.commit();
}
/* Exceptions handling. */
finally
{
if (transaction.isActive())
transaction.rollback();
em.close();
}
并添加一本书:
User user = /* ... */
Book book = new Book("A new book");
user.getBooks().add(book);
EntityManager em = /* ... */
EntityTransaction transaction = em.getTransaction();
try
{
transaction.begin();
/* user.getBooks().add(book); - placing this here doesn't change anything */
em.merge(user);
transaction.commit();
}
/* Exceptions handling. */
finally
{
if (transaction.isActive())
transaction.rollback();
em.close();
}
在我添加与用户一起创建的“测试”书之前,我看到的是第一本书实体的创建工作正常,但每当我创建另一个时,以前的一个以某种方式从数据存储中删除,并被我刚创建的新的替换(我可以告诉因为书的名字)。所以我不能为同一个用户创建多本书。
我试图看看我是否以某种方式搞砸了Book实体的持久性,因此我添加了“TEST”一书。问题仍然存在,只是现在我有了第一本书(“TEST”),每当我尝试添加一本新书时,我会不断更换列表中的第二本书。
同样,只有在我部署之后调试我的应用程序时才会发生这种情况。
我在调用em.persist(book)
之前尝试调用em.merge(user)
,但是这导致了一个例外情况,即该图书的所有者已经设置为持久且无法更改。我尝试自己设置关系(就像在此thread中一样),但是在添加图书时导致交易失败。
我不确定它是否相关,但我看到的“图书”列的类型是datastore_types.Key.from_path
,如:
[datastore_types.Key.from_path(u'User', 9001L, u'Book', 1L, _app=u's~myapp'),
datastore_types.Key.from_path(u'User', 9001L, u'Book', 2001L, _app=u's~myapp')]
任何帮助将不胜感激, 谢谢!
答案 0 :(得分:1)
你可以尝试下面的内容:
User user = /* ... */
Book book = new Book("A new book");
book.setOwner(user);
EntityManager em = /* ... */
EntityTransaction transaction = em.getTransaction();
try{
transaction.begin();
em.persist(user);
transaction.commit();
}finally{
if (transaction.isActive())
transaction.rollback();
em.close();
}