2

我正在尝试使用 cayenne 与 PostgreSQL 数据库进行交互。到目前为止,一切都按预期工作,但我现在遇到了一个我不太了解的问题(我是卡宴新手)。

假设我有一个包含常用字段(book_id、title、editor、price)的表“books”、一个“表”作者(author_id、author_name)和一个链接表“books_authors”(book_id、author_id)。

与添加或编辑一本书的过程相关的所有类共享一个 DataContext。

我有一个 struts2(我使用速度模板)表单,可以让您添加一本书,并使用 ajax 与多个作者关联。我对某个事件做出反应,触发一个调用 struts2 操作的 ajax 请求,该操作验证作者是否存在,然后将 Books_Authors 对象(由 cayenne 生成的类)添加到 struts2 会话(该操作实现 SessionAware)。

表格如下所示:

<form action="AddOrEditBook.do">
    <input type="hidden" name="book.book_id" value="$!book.book_id" />

    <input type="text" name="book.title" value="$!book.title" />

    <input type="text" name="book.editor" value="$!book.editor" />

    <input type="number" name="book.price" value="$!book.price" />

    <input type="text" name="author" /> <input type="button" name="addAuthor" value="Add" />

    <ul>
        <li id="author_2">Author 2 <input type="button" name="removeAuthor" value="Remove" /></li>
        <li id="author_16">Author 16 <input type="button" name="removeAuthor" value="Remove" /> </li>
    </ul>

    <input type="submit" />
</form>

一旦我将表单提交给 AddOrEditBook.do,它有一个用于 book 的 setter 和 getter,struts2 就会创建 book 对象并用表单的值填充它。那很好。

这是困扰我的事情:

当我更新一本书时,我没有找到使用struts创建的对象来更新db的方法。我想要实现的是以某种方式指示 cayenne 使用 struts 创建的对象来更新数据库中的相应实体。

我在 object_id、PersistenceState 等方面搞砸了很多:

Expression exp_book = ExpressionFactory.matchExp(Book.BOOK_ID_PROPERTY, book.getBook_id());
Book bookFromDb = RetrieveHelper.retrieveScalarByExpression(ctxt, new Book(), exp_book);

book.setObjectContext(ctxt);
book.setObjectId(bookFromDb.getObjectId());
ctxt.getObjectStore().registerNode(book.getObjectId(), book);
book.setPersistenceState(PersistenceState.MODIFIED);

使用 cayenne 更新数据库实体时正确的策略是什么?是否只能通过制作诸如 bookFromDb.setTitle(book.getTitle()); 之类的东西来做到这一点??

谢谢!

4

1 回答 1

1

struts2 创建 book 对象并用表单的值填充它。那很好。

我不是 Struts2 专家,但从我在有关表单对象生命周期的文档中阅读的内容来看,此类对象是由 Struts2 通过调用默认构造函数创建的。除非有一种方法可以覆盖此行为,否则将其替换为可以从正确的 DataContext 为您提供 Cayenne 对象的工厂,您在这里所做的是正确的 - 您正在分离附加到表单的值对象(以及动作类)来自持久对象。

使用 Tapestry 等其他框架,您可以直接将表单绑定到 Cayenne 持久对象。也许您也可以以类似的方式扩展 Struts2?

与添加或编辑一本书的过程相关的所有类共享一个 DataContext。

一条不相关的建议。您必须至少为每个用户拥有一个单独的 DataContext(例如,将其放在 HttpSession 中)。或者,如果您不在请求之间保持未提交状态 - 甚至每个请求可能有一个 DataContext。换句话说 - 不要共享 DataContexts,除非它们是只读的。否则你的应用程序不是线程安全的。

于 2012-06-11T08:05:59.807 回答