如何使用 JPA 创建本地数据库?
How to create local database using JPA?
我刚开始使用 JPA。我正在尝试使用 Persistence.generateSchema("DataLayer", null)
方法基于模式创建数据库,但出现异常。作为 JPA 实现,我正在使用 OpenJPA。
我的解决方案分为两个 Eclipse 项目。两者都使用 Maven 和 module-info.java.
第一个项目显然只是我调用上面方法的主要方法。
第二个是 JPA 实体和数据访问对象。
在第一个项目中,我包含了对第二个项目的依赖。在第二个项目中,我包含了对 jpa 实现程序 (openjpa) 和数据库驱动程序 (derby) 的依赖项。请参阅 pom.xml 的以下依赖项部分:
第一个项目依赖项(只有我的第二个项目):
<dependency>
<groupId>registry</groupId>
<artifactId>datalayer</artifactId>
<version>0.0.1</version>
</dependency>
第一个项目模块信息:
module justtestingTEMP
{
exports justtestingTEMP;
requires registry.datalayer;
requires javax.persistence;
}
第二个项目依赖项:
<dependencies>
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.15.2.0</version>
</dependency>
</dependencies>
第二个项目模块信息:
module registry.datalayer
{
exports datalayer.other;
exports datalayer.dto;
exports datalayer.dao;
requires javax.persistence;
}
这是persistence.xml(在第二个项目中):
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
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_2.xsd">
<persistence-unit name="DataLayer"
transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>myNonJtaDataSource</non-jta-data-source>
<properties>
<property
name="javax.persistence.schema-generation.database.action"
value="create" />
</properties>
</persistence-unit>
这是例外情况:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/sql/DataSource
at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.newInstance(JDBCBrokerFacto
ry.java:72)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Metho
d)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodA
ccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Delegatin
gMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.openjpa.kernel.Bootstrap.invokeFactory(Bootstrap.java:131)
at org.apache.openjpa.kernel.Bootstrap.newBrokerFactory(Bootstrap.java:66)
at org.apache.openjpa.persistence.PersistenceProviderImpl.getBrokerFactory(Pers
istenceProviderImpl.java:152)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFa
ctory(PersistenceProviderImpl.java:95)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFa
ctory(PersistenceProviderImpl.java:159)
at org.apache.openjpa.persistence.PersistenceProviderImpl.generateSchema(Persis
tenceProviderImpl.java:244)
at javax.persistence@1.1/javax.persistence.Persistence.generateSchema(Persisten
ce.java:188)
at justtestingTEMP/justtestingTEMP.Main.main(Main.java:15)
Caused by: java.lang.ClassNotFoundException: javax.sql.DataSource
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoade
r.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoa
ders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 13 more
我从哪里可以得到 javax.sql.DataSource class?我想我缺少一些依赖项或者我配置了错误。
我尝试了什么:切换 JPA 实现(引发了其他异常 - 但缺少 classes),将 requires java.sql;
添加到模块信息。
将 requires java.sql;
添加到模块信息后:
Exception in thread "main" java.lang.NoClassDefFoundError: java/lang /instrument/
ClassFileTransformer
at org.apache.openjpa.persistence.PersistenceProviderImpl.loadAgent(Persistence
ProviderImpl.java:365)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFa
ctory(PersistenceProviderImpl.java:102)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFa
ctory(PersistenceProviderImpl.java:159)
at org.apache.openjpa.persistence.PersistenceProviderImpl.generateSchema(Persis
tenceProviderImpl.java:244)
at javax.persistence@1.1/javax.persistence.Persistence.generateSchema(Persisten
ce.java:188)
at justtestingTEMP/justtestingTEMP.Main.main(Main.java:14)
Caused by: java.lang.ClassNotFoundException: java.lang.instrument.ClassFileTrans
former
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoade
r.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoa
ders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 6 more
发现需要的 classes 在 java.sql
和 java.instrument
模块中,所以将它们添加到模块信息中解决了我的问题。模块-info.java 应该是这样的:
module justtestingTEMP
{
exports justtestingTEMP;
requires java.instrument;
requires java.sql;
requires javax.persistence;
requires registry.datalayer;
}
也可以从第一个项目中删除模块-info.java。这导致了一个“正确的”错误,说我没有定义 jdbc 驱动程序和连接属性 - 这很好。没有 class 未找到错误。我现在可以创建并连接到数据库。这可能是因为所有必需的模块都是隐式可用的。使用 module-info.java 我必须定义所有必需的模块。
我刚开始使用 JPA。我正在尝试使用 Persistence.generateSchema("DataLayer", null)
方法基于模式创建数据库,但出现异常。作为 JPA 实现,我正在使用 OpenJPA。
我的解决方案分为两个 Eclipse 项目。两者都使用 Maven 和 module-info.java.
第一个项目显然只是我调用上面方法的主要方法。
第二个是 JPA 实体和数据访问对象。
在第一个项目中,我包含了对第二个项目的依赖。在第二个项目中,我包含了对 jpa 实现程序 (openjpa) 和数据库驱动程序 (derby) 的依赖项。请参阅 pom.xml 的以下依赖项部分:
第一个项目依赖项(只有我的第二个项目):
<dependency>
<groupId>registry</groupId>
<artifactId>datalayer</artifactId>
<version>0.0.1</version>
</dependency>
第一个项目模块信息:
module justtestingTEMP
{
exports justtestingTEMP;
requires registry.datalayer;
requires javax.persistence;
}
第二个项目依赖项:
<dependencies>
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.15.2.0</version>
</dependency>
</dependencies>
第二个项目模块信息:
module registry.datalayer
{
exports datalayer.other;
exports datalayer.dto;
exports datalayer.dao;
requires javax.persistence;
}
这是persistence.xml(在第二个项目中):
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
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_2.xsd">
<persistence-unit name="DataLayer"
transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>myNonJtaDataSource</non-jta-data-source>
<properties>
<property
name="javax.persistence.schema-generation.database.action"
value="create" />
</properties>
</persistence-unit>
这是例外情况:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/sql/DataSource
at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.newInstance(JDBCBrokerFacto
ry.java:72)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Metho
d)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodA
ccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Delegatin
gMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.openjpa.kernel.Bootstrap.invokeFactory(Bootstrap.java:131)
at org.apache.openjpa.kernel.Bootstrap.newBrokerFactory(Bootstrap.java:66)
at org.apache.openjpa.persistence.PersistenceProviderImpl.getBrokerFactory(Pers
istenceProviderImpl.java:152)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFa
ctory(PersistenceProviderImpl.java:95)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFa
ctory(PersistenceProviderImpl.java:159)
at org.apache.openjpa.persistence.PersistenceProviderImpl.generateSchema(Persis
tenceProviderImpl.java:244)
at javax.persistence@1.1/javax.persistence.Persistence.generateSchema(Persisten
ce.java:188)
at justtestingTEMP/justtestingTEMP.Main.main(Main.java:15)
Caused by: java.lang.ClassNotFoundException: javax.sql.DataSource
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoade
r.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoa
ders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 13 more
我从哪里可以得到 javax.sql.DataSource class?我想我缺少一些依赖项或者我配置了错误。
我尝试了什么:切换 JPA 实现(引发了其他异常 - 但缺少 classes),将 requires java.sql;
添加到模块信息。
将 requires java.sql;
添加到模块信息后:
Exception in thread "main" java.lang.NoClassDefFoundError: java/lang /instrument/
ClassFileTransformer
at org.apache.openjpa.persistence.PersistenceProviderImpl.loadAgent(Persistence
ProviderImpl.java:365)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFa
ctory(PersistenceProviderImpl.java:102)
at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFa
ctory(PersistenceProviderImpl.java:159)
at org.apache.openjpa.persistence.PersistenceProviderImpl.generateSchema(Persis
tenceProviderImpl.java:244)
at javax.persistence@1.1/javax.persistence.Persistence.generateSchema(Persisten
ce.java:188)
at justtestingTEMP/justtestingTEMP.Main.main(Main.java:14)
Caused by: java.lang.ClassNotFoundException: java.lang.instrument.ClassFileTrans
former
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoade
r.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoa
ders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 6 more
发现需要的 classes 在 java.sql
和 java.instrument
模块中,所以将它们添加到模块信息中解决了我的问题。模块-info.java 应该是这样的:
module justtestingTEMP
{
exports justtestingTEMP;
requires java.instrument;
requires java.sql;
requires javax.persistence;
requires registry.datalayer;
}
也可以从第一个项目中删除模块-info.java。这导致了一个“正确的”错误,说我没有定义 jdbc 驱动程序和连接属性 - 这很好。没有 class 未找到错误。我现在可以创建并连接到数据库。这可能是因为所有必需的模块都是隐式可用的。使用 module-info.java 我必须定义所有必需的模块。