【问题标题】:JDO bidirectional one to many relationship add objectJDO双向一对多关系添加对象
【发布时间】:2014-03-17 11:40:15
【问题描述】:

我有一个 Autor 类和一个 Dokument 类,它们是双向的 1 到 n 列表关系(1 个 Autor 可以编写多个文档),我想将它们保存到 Cloud SQL 中。 orm 在 package.jdo 和 package-cloudsql.orm 中指定。

文档类:

public class Autor {

    private String aid;

    private String vorname;

    private String nachname;

    private List<Dokument> dokumente;

    public Autor() {

    }

    public Autor(String vorname, String nachname) {
        this.vorname = vorname;
        this.nachname = nachname;
        this.dokumente = new ArrayList<Dokument>();
    }

    public String getAID() {
        return aid;
    }

    public String getVorname() {
        return vorname;
    }

    public String getNachname() {
        return nachname;
    }

    public List<Dokument> getDokumente() {
        return this.dokumente;
    }

    public void setAID(String aid) {
        this.aid = aid;
    }

    public void setVorname(String vorname) {
        this.vorname = vorname;
    }

    public void setNachname(String nachname) {
        this.nachname = nachname;
    }

    public void addDokument(Dokument dokument) {
        this.dokumente.add(dokument);
    }

    public void deleteDokument(Dokument dokument) {
        this.dokumente.remove(dokument);
    }

    public void deleteAllDokumente() {
        this.dokumente.clear();
    }

}

文档类:

public class Dokument {

    private String did;

    private Autor autor;

    private String titel;

    private String text;

    private Date datum;

    public Dokument() {

    }

    public Dokument(Autor autor, String titel, String text, Date datum) {
        this.autor = autor;
        this.titel = titel;
        this.text = text;
        this.datum = datum;
    }

    public Dokument(String titel, String text, Date datum) {
        this.autor = null;
        this.titel = titel;
        this.text = text;
        this.datum = datum;
    }

    public String getDid() {
        return did;
    }

    public Autor getAutor() {
        return autor;
    }

    public String getTitel() {
        return titel;
    }

    public String getText() {
        return text;
    }

    public Date getDatum() {
        return datum;
    }

    public void setDID(String did) {
        this.did = did;
    }

    public void setAutor(Autor autor) {
        this.autor = autor;
    }

    public void setTitel(String titel) {
        this.titel = titel;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setDatum(Date date) {
        this.datum = date;
    }
}

package.jdo 包含以下内容:

<class name="Autor" detachable="true" identity-type="application">
            <field name="aid" primary-key="true" persistence-modifier="persistent" value-strategy="identity"/>
            <field name="vorname"/>
            <field name="nachname" />
            <field name="dokumente"/>       
        </class>
        <class name="Dokument" detachable="true" identity-type="application">
            <field name="did" primary-key="true" persistence-modifier="persistent" value-strategy="identity"/>
            <field name="autor"/>
            <field name="titel"/>
            <field name="text"/>
            <field name="datum"/>
        </class>

package-sql.orm 包含以下内容:

<class name="Autor" detachable="true" persistence-modifier="persistence-capable" table="Autor">
            <field name="aid" primary-key="true" persistence-modifier="persistent" value-strategy="identity">
                <column name="aid" jdbc-type="bigint" length="20"/>
            </field>
            <field name="vorname" persistence-modifier="persistent">
                <column name="vorname"/>
            </field>    
            <field name="nachname" persistence-modifier="persistent">
                <column name="nachname"/>
            </field>
            <field name="dokumente" persistence-modifier="persistent" mapped-by="autor">
                <collection element-type="de.hdm.studienarbeit3.dokumente.Dokument"/>
            </field>
        </class>
        <class name="Dokument" detachable="true" persistence-modifier="persistence-capable" table="Dokument">
            <field name="did" primary-key="true" persistence-modifier="persistent" value-strategy="identity">
                <column name="did" jdbc-type="bigint" length="20" />
            </field>
            <field name="autor" persistence-modifier="persistent" default-fetch-group="true">
                <column name="autor" jdbc-type="bigint" length="20"/>
                <foreign-key name="DOKUMENTAUTOR_FK" delete-action="restrict"/>
            </field>
            <field name="titel" persistence-modifier="persistent">
                <column name="titel"/>
            </field>
            <field name="text" persistence-modifier="persistent">
                <column name="text"/>
            </field>
            <field name="datum" persistence-modifier="persistent">
                <column name="datum"/>
            </field>
        </class>

所以我想向现有的 Autor 添加第二个(第三个等等)文档。但是每次我坚持一个文档时,它也会创建一个具有我选择的 Autor 属性的新 Autor。 例如,我有一个 ID 为 1 的 Autor,名称为“Hans Maier”,并希望创建另一个文档,并以他为 Autor,但新文档将有一个 ID 为 2 的 Autor,并且名称为“Hans Maier”,这是不希望的。我希望新文档也连接到 Autor 1。

我的 servlet 中有这段代码:

if (autoraid=="") {
  if (vorname == "" | nachname =="") {
    resp.getWriter().println("Bitte Autor auswählen oder Namen vollständig ausfüllen.");
  } else {
     Autor autor = new Autor(vorname, nachname);
     Dokument dokument = new Dokument(autor, titel, text, datum);
     autor.addDokument(dokument);
     DokumentDAO dokumentDao = new DokumentDAO(pmf);
     dokumentDao.addDokument(autor, dokument);
 }
} else {
    AutorDAO autorDao = new AutorDAO(pmf);
    Autor autor = autorDao.getAutor(autoraid);
    Dokument dokument = new Dokument(autor, titel, text, datum);
    autor.addDokument(dokument);
    DokumentDAO dokumentDao = new DokumentDAO(pmf);
    dokumentDao.addDokument(autor, dokument);
}

autorDao.getAutor 返回它通过密钥获取的 autor(这有效),dokumentDao.addDokument() 使用 pm.makePersistent(dokument) 持久化给定的文档

我错过了什么或做错了什么? Datanucleus 文档说,在双向关系http://www.datanucleus.org/products/accessplatform/jdo/orm/relationships.html 上使用 List 时,我必须设置两端,我在 Dokument creator 和 autor.addDokument() 上设置 Autor,但它不起作用。

如果我在持久化之前阅读了dokument.getAutor().getAID(),它会返回我希望它连接到的Autor 的正确ID,但在数据库中它是一个新的Autor。我怎样才能让它正常工作?

我已经阅读了这个http://www.onjava.com/pub/a/onjava/excerpt/chap_07/index2.html,createBook 方法正是我想要做的,所以我也测试了做

public void addDokument(Autor autor, Dokument dokument) {

    PersistenceManager pm = pmf.getPersistenceManager();
    Transaction tx = pm.currentTransaction();

    try {

      tx.begin();
        dokument.setAutor(autor);
        autor.addDokument(dokument);            
        pm.makePersistent(dokument);

       tx.commit();

    } catch (Exception e) {
      System.out.println("Exception: " + e.getMessage());

    } finally {
      if (tx.isActive()) {
        tx.rollback();
      }
      pm.close();
    }
    }

在事务中,但结果相同,创建了一个新的 Autor。

我们将不胜感激。

日志如下:

Feb 18, 2014 1:23:33 PM org.datanucleus.store.rdbms.mapping.MappedTypeManager addMappedType
Schwerwiegend: User-defined type mapping class "org.datanucleus.store.mapped.mapping.LocalDateMapping" was not found. Please check the mapping file class specifications and your CLASSPATH. The class must be in the CLASSPATH.
Feb 18, 2014 1:23:33 PM org.datanucleus.store.rdbms.mapping.MappedTypeManager addMappedType
Schwerwiegend: User-defined type mapping class "org.datanucleus.store.mapped.mapping.LocalDateTimeMapping" was not found. Please check the mapping file class specifications and your CLASSPATH. The class must be in the CLASSPATH.
Feb 18, 2014 1:23:33 PM org.datanucleus.store.rdbms.mapping.MappedTypeManager addMappedType
Schwerwiegend: User-defined type mapping class "org.datanucleus.store.mapped.mapping.LocalTimeMapping" was not found. Please check the mapping file class specifications and your CLASSPATH. The class must be in the CLASSPATH.
Feb 18, 2014 1:23:39 PM org.datanucleus.store.rdbms.query.ForwardQueryResult closingConnection
Information: Reading in results for query "SELECT FROM de.hdm.studienarbeit3.dokumente.Autor ORDER BY nachname asc" since the connection used is closing
Feb 18, 2014 1:23:52 PM org.datanucleus.store.rdbms.mapping.MappedTypeManager addMappedType
Schwerwiegend: User-defined type mapping class "org.datanucleus.store.mapped.mapping.LocalDateMapping" was not found. Please check the mapping file class specifications and your CLASSPATH. The class must be in the CLASSPATH.
Feb 18, 2014 1:23:52 PM org.datanucleus.store.rdbms.mapping.MappedTypeManager addMappedType
Schwerwiegend: User-defined type mapping class "org.datanucleus.store.mapped.mapping.LocalDateTimeMapping" was not found. Please check the mapping file class specifications and your CLASSPATH. The class must be in the CLASSPATH.
Feb 18, 2014 1:23:52 PM org.datanucleus.store.rdbms.mapping.MappedTypeManager addMappedType
Schwerwiegend: User-defined type mapping class "org.datanucleus.store.mapped.mapping.LocalTimeMapping" was not found. Please check the mapping file class specifications and your CLASSPATH. The class must be in the CLASSPATH.

org.datanucleus.store.mapped.mapping.* 曾经在 datanucleus-core 中(至少在 3.1.3 版中),但现在在 3.2.9 版中。它不存在了吗?它去哪儿了? datanucleus-rdbms 也是 3.2.9 版本。

System.getProperty("java.class.path")的输出

[workspace]\studienarbeit3\war\WEB-INF\classes
[workspace]\studienarbeit3\war\WEB-INF\lib\mysql-connector-java-5.1.28-bin.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\shared\appengine-local-runtime-shared.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\shared\el-api.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\shared\jsp\repackaged-appengine-ant-1.7.1.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\shared\jsp\repackaged-appengine-ant-launcher-1.7.1.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\shared\jsp\repackaged-appengine-jasper-6.0.29.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\shared\jsp\repackaged-appengine-jasper-el-6.0.29.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\shared\jsp\repackaged-appengine-tomcat-juli-6.0.29.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\shared\jsp-api.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\shared\servlet-api.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\appengine-tools-api.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\appengine-api-labs\v1\appengine-api-labs.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\appengine-endpoints\v1\appengine-endpoints-deps.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\appengine-endpoints\v1\appengine-endpoints.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\jsr107\v1\appengine-jsr107cache-1.8.9.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\jsr107\v1\jsr107cache-1.1.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\user\appengine-api-1.0-sdk-1.8.9.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\datanucleus\v3\asm-4.0.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\datanucleus\v3\datanucleus-api-jdo-3.2.8.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\datanucleus\v3\datanucleus-appengine-3.0.0.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\datanucleus\v3\datanucleus-core-3.2.9.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\datanucleus\v3\datanucleus-rdbms-3.2.9.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\datanucleus\v3\jdo-api-3.1-rc1.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\opt\user\datanucleus\v3\jta-1.1.jar
[workspace]\studienarbeit3\war\WEB-INF\lib\javax.servlet.jsp.jstl-1.2.1.jar
[workspace]\studienarbeit3\war\WEB-INF\lib\javax.servlet.jsp.jstl-api-1.2.1.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\impl\google_sql.jar
[eclipse]\plugins\com.google.appengine.eclipse.sdkbundle_1.8.9\appengine-java-sdk-1.8.9\lib\agent\appengine-agent.jar

【问题讨论】:

  • “它不起作用”。那么为什么不精确呢?日志说什么?它告诉您有关对象生命周期等的信息,对象在持久化时所处的状态,并且您不提供类或确切的持久性代码,因此人们只剩下猜测。日志就是针对这种情况的(请不要回来说“日志中什么都没有”,因为使用DEBUG级别时它会是一个大文件)。
  • 我想为您提供日志,但我不知道它在哪里。你能告诉我在哪里可以找到它吗?我已经从这里datanucleus.org/products/accessplatform/logging.html 复制了 java.util.logging 示例,但找不到任何输出
  • 我已经添加了类和DokumentDao.addDokument(Autor autor, Dokument dokument)的代码
  • 日志是您将其配置为的位置...您的日志配置定义了文件名。这是 java.util.logging 标准,因此了解独立于 DataNucleus 的有用信息
  • 好的,我找到了文件,我应该阅读他们提供的更好的 cmets,但是我必须设置哪些级别才能获得有用的输出?我现在已经全部使用了,并且持久化不会创建任何日志条目,只是检索数据会创建一个日志条目,并且由于某些日期/时间映射而存在致命异常,我会将其插入我的帖子中,以便您可以看到它

标签: java google-app-engine jdo datanucleus google-cloud-sql


【解决方案1】:

正如Google's compatibility doc 所说,他们的 GAE/Datastore 插件 (datanucleus-appengine) 仅与 DataNucleus 3.1 兼容。在 DataNucleus Maven repo 中有一个build of 他们的插件(与 DataNucleus 3.2/3.3 一起使用)的 SVN(但问 Google 为什么他们懒得发布这个,它在他们的 SVN 中已经存在一年或更长时间了)。您的另一个线程说您需要 DataNucleus 3.2+ 才能与 Google Cloud SQL 一起使用。总之,很明显为什么不能混合和匹配 DataNucleus jar 版本;选择您正在使用的版本并获取合适的 jars。

【讨论】:

  • 实际上我正在使用这个 Datanucleus-AppEngine-Plugin-3.0。来自我构建路径中的 Datanucleus 网站。
  • 所以查看日志,因为只有你才能看到所有这些 jar 的版本实际上在 CLASSPATH 中。
  • 我已经添加了 WEB-INF/lib 中的 jar 列表,我没有看到任何丢失或过时的版本(没有 datanucleus-api-jdo-3.2.9. jar 在 maven 存储库中,accessplatform 3.3.7 还附带此版本以及版本 3.2.9 中的核心和 rdbms。)
  • 这只是 CLASSPATH 的一部分。 System.getProperty("java.class.path") 可能会显示更多。您的消息声称找不到某些 mapped.mapping 类,但它显然在 datanucleus-appengine-3.0.0.jar 中(您可以轻松检查)。如果找不到,则该 jar 被隐藏(被其他东西...)
  • 好的,我已经用 System.getProperty("java.class.path") 的输出替换了它。 Datanucleus 也列出来了,它被什么隐藏了?
猜你喜欢
  • 2018-10-28
  • 1970-01-01
  • 2013-04-17
  • 1970-01-01
  • 2010-12-30
  • 2013-11-11
  • 1970-01-01
  • 2015-03-15
  • 2012-11-22
相关资源
最近更新 更多