连接 PersistenceManagerFactory 和 Persistence.xml 时出错

Error in connecting PersistenceManagerFactoryand Persistence.xml

我的目标是在java中使用datanucleus、h2数据库做CRUD操作。但卡在连接 PersistenceManagerFactory 和 persistence.xml

我尝试过不同版本的 datanucleus-core、h2database、datanucleus-api-jdo。我目前参考的是官方文档:http://www.datanucleus.org/products/accessplatform/jdo/getting_started.html

主要代码文件

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

public class Main {
    public static void main(String[] args)
    {
        PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("Tutorial");
        PersistenceManager pm = pmf.getPersistenceManager();

        pm.currentTransaction().begin();
        try {
            Users user = new Users();
            user.setId(1);
            user.setUser("himmat");
            user.setEmail("xyz@gmail.com");
            user.setMobileNo("7896585687");
            pm.currentTransaction().commit();
        }finally {
            if(pm.currentTransaction().isActive())
            {
                pm.currentTransaction().rollback();
            }
            pm.close();
        }
    }
}

persistence.xml

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1">

    <!-- JDO tutorial "unit" -->
    <persistence-unit name="Tutorial">
        <class>Users</class>
        <exclude-unlisted-classes/>
        <properties>
            <property name="javax.jdo.option.ConnectionURL" value="jdbc:h2:mem:nucleus1"/>
            <property name="javax.jdo.option.ConnectionUserName" value="sa"/>
            <property name="javax.jdo.option.ConnectionPassword" value=""/>
            <property name="datanucleus.schema.autoCreateAll" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

错误代码

"C:\Program Files\Java\jdk1.8.0_211\bin\java.exe" "-javaagent:C:\Users\shyam\AppData\Local\JetBrains\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar=56680:C:\Users\shyam\AppData\Local\JetBrains\IntelliJ IDEA 2019.1.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_211\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\rt.jar;C:\Users\shyam\eclipse-workspace\DemoJDO\target\classes;C:\Users\shyam\.m2\repository\org\datanucleus\datanucleus-api-jdo.2.1\datanucleus-api-jdo-5.2.1.jar;C:\Users\shyam\.m2\repository\org\datanucleus\datanucleus-core.2.1\datanucleus-core-5.2.1.jar;C:\Users\shyam\.m2\repository\org\datanucleus\datanucleus-rdbms.2.1\datanucleus-rdbms-5.2.1.jar;C:\Users\shyam\.m2\repository\javax\jdo\jdo-api.0.1\jdo-api-3.0.1.jar;C:\Users\shyam\.m2\repository\javax\transaction\jta.1\jta-1.1.jar" Main
Exception in thread "main" javax.jdo.JDOFatalUserException: A property named javax.jdo.PersistenceManagerFactoryClass must be specified, or a jar file with a META-INF/services/javax.jdo.PersistenceManagerFactory entry must be in the classpath, or a property named javax.jdo.option.PersistenceUnitName must be specified.
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:861)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:1099)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:919)
    at Main.main(Main.java:8)
NestedThrowablesStackTrace:
javax.jdo.JDOException: Errors were encountered when loading the MetaData for the persistence-unit "Tutorial". See the nested exceptions for details
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.initialiseMetaData(JDOPersistenceManagerFactory.java:807)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.<init>(JDOPersistenceManagerFactory.java:600)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.createPersistenceManagerFactory(JDOPersistenceManagerFactory.java:316)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.getPersistenceManagerFactory(JDOPersistenceManagerFactory.java:225)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javax.jdo.JDOHelper.run(JDOHelper.java:1965)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.jdo.JDOHelper.invoke(JDOHelper.java:1960)
    at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1166)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:844)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:1099)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:919)
    at Main.main(Main.java:8)
NestedThrowablesStackTrace:
Errors were encountered when loading the MetaData for the persistence-unit "Tutorial". See the nested exceptions for details
org.datanucleus.exceptions.NucleusUserException: Errors were encountered when loading the MetaData for the persistence-unit "Tutorial". See the nested exceptions for details
    at org.datanucleus.metadata.MetaDataManagerImpl.loadPersistenceUnit(MetaDataManagerImpl.java:1124)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.initialiseMetaData(JDOPersistenceManagerFactory.java:797)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.<init>(JDOPersistenceManagerFactory.java:600)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.createPersistenceManagerFactory(JDOPersistenceManagerFactory.java:316)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.getPersistenceManagerFactory(JDOPersistenceManagerFactory.java:225)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javax.jdo.JDOHelper.run(JDOHelper.java:1965)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.jdo.JDOHelper.invoke(JDOHelper.java:1960)
    at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1166)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:844)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:1099)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:919)
    at Main.main(Main.java:8)
Caused by: java.lang.NoClassDefFoundError: javax/jdo/AttributeConverter$UseDefault
    at org.datanucleus.api.jdo.metadata.JDOAnnotationReader.processMemberAnnotations(JDOAnnotationReader.java:955)
    at org.datanucleus.metadata.annotations.AbstractAnnotationReader.getMetaDataForClass(AbstractAnnotationReader.java:251)
    at org.datanucleus.metadata.annotations.AnnotationManagerImpl.getMetaDataForClass(AnnotationManagerImpl.java:190)
    at org.datanucleus.metadata.MetaDataManagerImpl.loadAnnotationsForClass(MetaDataManagerImpl.java:2818)
    at org.datanucleus.metadata.MetaDataManagerImpl.loadPersistenceUnit(MetaDataManagerImpl.java:1095)
    ... 16 more
Caused by: java.lang.ClassNotFoundException: javax.jdo.AttributeConverter$UseDefault
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 21 more
Nested Throwables StackTrace:
java.lang.NoClassDefFoundError: javax/jdo/AttributeConverter$UseDefault
    at org.datanucleus.api.jdo.metadata.JDOAnnotationReader.processMemberAnnotations(JDOAnnotationReader.java:955)
    at org.datanucleus.metadata.annotations.AbstractAnnotationReader.getMetaDataForClass(AbstractAnnotationReader.java:251)
    at org.datanucleus.metadata.annotations.AnnotationManagerImpl.getMetaDataForClass(AnnotationManagerImpl.java:190)
    at org.datanucleus.metadata.MetaDataManagerImpl.loadAnnotationsForClass(MetaDataManagerImpl.java:2818)
    at org.datanucleus.metadata.MetaDataManagerImpl.loadPersistenceUnit(MetaDataManagerImpl.java:1095)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.initialiseMetaData(JDOPersistenceManagerFactory.java:797)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.<init>(JDOPersistenceManagerFactory.java:600)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.createPersistenceManagerFactory(JDOPersistenceManagerFactory.java:316)
    at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.getPersistenceManagerFactory(JDOPersistenceManagerFactory.java:225)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javax.jdo.JDOHelper.run(JDOHelper.java:1965)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.jdo.JDOHelper.invoke(JDOHelper.java:1960)
    at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1166)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:844)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:1099)
    at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:919)
    at Main.main(Main.java:8)
Caused by: java.lang.ClassNotFoundException: javax.jdo.AttributeConverter$UseDefault
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 21 more

Process finished with exit code 1

您可以使用属性代替 persistence.xml 实际上,我已经使用属性做了一个类似的例子。另一个问题是你可能缺少一些依赖项,我正在分享 pom.xml。尝试使用你可能会得到结果。如果您使用 Maven,这很容易做到。您还需要对其进行增强,如官方文档中所示。

http://www.datanucleus.org/products/accessplatform/jdo/getting_started.html

为此,您需要关注

http://www.datanucleus.org/products/accessplatform_3_2/jdo/enhancer.html

POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.automated</groupId>
    <artifactId>DemoJDO</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-api-jdo</artifactId>
            <version>5.2.1</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.199</version>
        </dependency>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-rdbms</artifactId>
            <version>5.2.1</version>
        </dependency>
        <dependency>
            <groupId>javax.jdo</groupId>
            <artifactId>jdo-api</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
                <groupId>org.datanucleus</groupId>
                <artifactId>datanucleus-core</artifactId>
                <version>5.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>javax.jdo</artifactId>
            <version>3.2.0-m3</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.datanucleus</groupId>
                <artifactId>datanucleus-maven-plugin</artifactId>
                <version>3.2.0-m3</version>
                <configuration>
                    <log4jConfiguration>${basedir}/log4j.properties</log4jConfiguration>
                    <verbose>true</verbose>
                </configuration>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

主文件代码

public static void main(String[] args)
    {
        Properties properties = new Properties();
        properties.setProperty("javax.jdo.PersistenceManagerFactoryClass",
                "org.datanucleus.api.jdo.JDOPersistenceManagerFactory");
        properties.setProperty("javax.jdo.option.ConnectionDriverName","org.h2.Driver");
        properties.setProperty("javax.jdo.option.ConnectionURL","jdbc:h2:~/test");
        properties.setProperty("javax.jdo.option.ConnectionUserName","sa");
        properties.setProperty("javax.jdo.option.ConnectionPassword","");
        properties.setProperty("datanucleus.schema.autoCreateAll","true");

        PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(properties);
        PersistenceManager pm = pmf.getPersistenceManager();

 pm.currentTransaction().begin();
try {
//...
//You can use your logic here
//...
            pm.currentTransaction().commit();
        }finally {
            if(pm.currentTransaction().isActive())
            {
                pm.currentTransaction().rollback();
            }
            pm.close();
        }

}