JPA:如何使用@NamedQuery 从不同的 DB2 模式中指定表。 Schema.Table 不能是 FROM 子句的第一个声明
JPA: How to specify tables from different DB2 schemas using @NamedQuery. Schema.Table cannot be the first declaration of the FROM clause
我在从 Postman 发送 GET 请求以测试我的端点时遇到问题。相同的 NamedQueries 之前只使用一个模式与 Derby 一起工作,因此无需区分。我现在已经在本地 Docker 实例中更改为 DB2 运行ning 并使用 Maven 到 运行 Open-Liberty Framework 来创建端点。我收到以下错误。我是否需要创建一个带有实体映射的 orm.xml 文件,或者做其他事情来解决这个问题?如果可能的话,我宁愿在没有更多 xml 文件的情况下执行此操作。
邮递员:
Error 500: java.lang.NullPointerException: Cannot invoke >"javax.persistence.EntityManager.createNamedQuery(String, java.lang.Class)" because "this.em" is null
马文:
[INFO] [ERROR ] CWWJP0015E: An error occurred in the org.eclipse.persistence.jpa.PersistenceProvider persistence provider when it attempted to create the container entity manager factory for the jpa-unit persistence unit. The following error occurred: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.7.9.v20210604-2c549e2208): org.eclipse.persistence.exceptions.EntityManagerSetupException
[INFO] Exception Description: Deployment of PersistenceUnit [jpa-unit] failed. Close all factories for this PersistenceUnit.
[INFO] Internal Exception: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.9.v20210604-2c549e2208): org.eclipse.persistence.exceptions.JPQLException
[INFO] Exception Description: Problem compiling [SELECT u FROM Sankofa.Users u].
[INFO] [14, 29] 'Sankofa.Users u' cannot be the first declaration of the FROM clause.
UserDao
package dao;
import java.util.List;
import java.util.concurrent.TimeoutException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.hyperledger.fabric.gateway.ContractException;
import javax.enterprise.context.RequestScoped;
import models.*;
@RequestScoped
public class UserDao {
//DB2 Methods
@PersistenceContext(name = "jpa-unit")
private EntityManager em;
public void createUser(Users user){
em.persist(user);
}
public Users readUser(int userID){
return em.find(Users.class, userID);
}
//NEED TO DO set return limit to 20
public List<Users> readAllUsers(){
return em.createNamedQuery("Users.findAll", Users.class).getResultList();
}
public void updateUser(Users user){
em.merge(user);
}
public void deleteUser(Users userID){
em.remove(userID);
}
public List<Users> findUser(String email){
return em.createNamedQuery("Users.findUser", Users.class)
.setParameter("email", email)
.getResultList();
}
public void createHistory(History hist){
em.persist(hist);
}
//wait this doesnt do anything?
public Users readHistory(int userID){
return em.find(Users.class, userID);
}
public List<History> readAllHistory(){
return em.createNamedQuery("History.findAll", History.class).getResultList();
}
}
用户
package models;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.persistence.*;
import java.time.LocalDate;
@Entity
@Table(name = "Users")
@NamedQueries({
@NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
@NamedQuery(name = "Users.findUser", query = "SELECT usr FROM Users usr WHERE usr.email = :email")
})
public class Users {
private static JsonObjectBuilder builder = Json.createObjectBuilder();
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
@Column(name = "userId")
private int id;
@Column(name = "firstName")
private String firstName;
@Column(name = "lastName")
private String lastName;
@Column(name = "gender")
private String gender;
@Column(name = "address")
private String address;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Column(name = "dateOfBirth")
private LocalDate dateOfBirth;
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="jpa-unit" transaction-type="JTA">
<mapping-file>orm.xml</mapping-file>
<properties>
<!-- Connection Specific -->
<property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect"/>
<property name="javax.persistence.schema-generation.database.action" value="create" />
<property name="javax.persistence.schema-generation.create-database-schemas" value="true" />
<property name="javax.persistence.schema-generation.scripts.action" value="create" />
<property name="javax.persistence.schema-generation.scripts.create-target" value="create.ddl"/>
</properties>
</persistence-unit>
</persistence>
Server.xml
<server description="Obdoblock REST Server">
<featureManager>
<feature>jaxrs-2.1</feature>
<feature>openapi-3.1</feature>
<feature>jpa-2.2</feature>
<feature>cdi-2.0</feature>
</featureManager>
<httpEndpoint
httpPort="${default.http.port}"
httpsPort="${default.https.port}"
id="defaultHttpEndpoint"
host="*"
/>
<webApplication
location="hyperledger-api.war"
contextRoot="${app.context.root}"
/>
<!-- DB2 Library Configuration -->
<library id="DB2JCCLib">
<file name="${shared.resource.dir}/jcc-11.5.6.0" />
</library>
<dataSource id="DefaultDataSource" jndiName="jdbc/db2">
<jdbcDriver libraryRef="jdbcLib"/>
<properties.db2.jcc
databaseName="testdb"
serverName="localhost"
portNumber="50000"
user="****" password="****"
/>
</dataSource>
</server>
版本:
- Docker:20.10.8,构建 3967b7d
- DB2: ibm/db2 docker 映像版本 11.5.6
- 行家:3.8.3
- Java: JDK 14.0.2
如果需要更多详细信息,我很乐意提供。谢谢,迪伦
How to specify tables from different DB2 schemas using @NamedQuery
据我所知,您不能在查询级别配置架构值。预计在实体下定义的所有命名查询都将针对同一架构执行。
可以通过 orm.xml 映射文件在持久性单元级别设置数据库模式:
orm.xml
<entity-mappings ... >
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>Sankofa</schema>
</persistence-unit-defaults>
</persistence-unit-metadata>
. . .
</entity-mappings>
persistence.xml
<persistence ... >
<persistence-unit name="foo">
<mapping-file>orm.xml</mapping-file>
</persistence-unit>
</persistence>
对于EclipseLink,可以配置一个SessionCustomizerclass
public class FooSessionCustomizer
implements org.eclipse.persistence.config.SessionCustomizer {
@Override
public void customize(Session session) throws Exception {
session.getLogin().setTableQualifier("Sankofa");
}
}
persistence.xml
<persistence ... >
<persistence-unit name="foo">
<properties>
<property name="eclipselink.session.customizer" value="foo.customizer.FooSessionCustomizer" />
</properties>
</persistence-unit>
</persistence>
@Table 注释有一个“schema”元素,用于在实体级别配置模式
@Table(name = "Users", schema = "Sankofa")
我在从 Postman 发送 GET 请求以测试我的端点时遇到问题。相同的 NamedQueries 之前只使用一个模式与 Derby 一起工作,因此无需区分。我现在已经在本地 Docker 实例中更改为 DB2 运行ning 并使用 Maven 到 运行 Open-Liberty Framework 来创建端点。我收到以下错误。我是否需要创建一个带有实体映射的 orm.xml 文件,或者做其他事情来解决这个问题?如果可能的话,我宁愿在没有更多 xml 文件的情况下执行此操作。
邮递员:
Error 500: java.lang.NullPointerException: Cannot invoke >"javax.persistence.EntityManager.createNamedQuery(String, java.lang.Class)" because "this.em" is null
马文:
[INFO] [ERROR ] CWWJP0015E: An error occurred in the org.eclipse.persistence.jpa.PersistenceProvider persistence provider when it attempted to create the container entity manager factory for the jpa-unit persistence unit. The following error occurred: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.7.9.v20210604-2c549e2208): org.eclipse.persistence.exceptions.EntityManagerSetupException
[INFO] Exception Description: Deployment of PersistenceUnit [jpa-unit] failed. Close all factories for this PersistenceUnit.
[INFO] Internal Exception: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.9.v20210604-2c549e2208): org.eclipse.persistence.exceptions.JPQLException
[INFO] Exception Description: Problem compiling [SELECT u FROM Sankofa.Users u].
[INFO] [14, 29] 'Sankofa.Users u' cannot be the first declaration of the FROM clause.
UserDao
package dao;
import java.util.List;
import java.util.concurrent.TimeoutException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.hyperledger.fabric.gateway.ContractException;
import javax.enterprise.context.RequestScoped;
import models.*;
@RequestScoped
public class UserDao {
//DB2 Methods
@PersistenceContext(name = "jpa-unit")
private EntityManager em;
public void createUser(Users user){
em.persist(user);
}
public Users readUser(int userID){
return em.find(Users.class, userID);
}
//NEED TO DO set return limit to 20
public List<Users> readAllUsers(){
return em.createNamedQuery("Users.findAll", Users.class).getResultList();
}
public void updateUser(Users user){
em.merge(user);
}
public void deleteUser(Users userID){
em.remove(userID);
}
public List<Users> findUser(String email){
return em.createNamedQuery("Users.findUser", Users.class)
.setParameter("email", email)
.getResultList();
}
public void createHistory(History hist){
em.persist(hist);
}
//wait this doesnt do anything?
public Users readHistory(int userID){
return em.find(Users.class, userID);
}
public List<History> readAllHistory(){
return em.createNamedQuery("History.findAll", History.class).getResultList();
}
}
用户
package models;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.persistence.*;
import java.time.LocalDate;
@Entity
@Table(name = "Users")
@NamedQueries({
@NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
@NamedQuery(name = "Users.findUser", query = "SELECT usr FROM Users usr WHERE usr.email = :email")
})
public class Users {
private static JsonObjectBuilder builder = Json.createObjectBuilder();
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
@Column(name = "userId")
private int id;
@Column(name = "firstName")
private String firstName;
@Column(name = "lastName")
private String lastName;
@Column(name = "gender")
private String gender;
@Column(name = "address")
private String address;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Column(name = "dateOfBirth")
private LocalDate dateOfBirth;
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="jpa-unit" transaction-type="JTA">
<mapping-file>orm.xml</mapping-file>
<properties>
<!-- Connection Specific -->
<property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect"/>
<property name="javax.persistence.schema-generation.database.action" value="create" />
<property name="javax.persistence.schema-generation.create-database-schemas" value="true" />
<property name="javax.persistence.schema-generation.scripts.action" value="create" />
<property name="javax.persistence.schema-generation.scripts.create-target" value="create.ddl"/>
</properties>
</persistence-unit>
</persistence>
Server.xml
<server description="Obdoblock REST Server">
<featureManager>
<feature>jaxrs-2.1</feature>
<feature>openapi-3.1</feature>
<feature>jpa-2.2</feature>
<feature>cdi-2.0</feature>
</featureManager>
<httpEndpoint
httpPort="${default.http.port}"
httpsPort="${default.https.port}"
id="defaultHttpEndpoint"
host="*"
/>
<webApplication
location="hyperledger-api.war"
contextRoot="${app.context.root}"
/>
<!-- DB2 Library Configuration -->
<library id="DB2JCCLib">
<file name="${shared.resource.dir}/jcc-11.5.6.0" />
</library>
<dataSource id="DefaultDataSource" jndiName="jdbc/db2">
<jdbcDriver libraryRef="jdbcLib"/>
<properties.db2.jcc
databaseName="testdb"
serverName="localhost"
portNumber="50000"
user="****" password="****"
/>
</dataSource>
</server>
版本:
- Docker:20.10.8,构建 3967b7d
- DB2: ibm/db2 docker 映像版本 11.5.6
- 行家:3.8.3
- Java: JDK 14.0.2
如果需要更多详细信息,我很乐意提供。谢谢,迪伦
How to specify tables from different DB2 schemas using @NamedQuery
据我所知,您不能在查询级别配置架构值。预计在实体下定义的所有命名查询都将针对同一架构执行。
可以通过 orm.xml 映射文件在持久性单元级别设置数据库模式:
orm.xml
<entity-mappings ... > <persistence-unit-metadata> <persistence-unit-defaults> <schema>Sankofa</schema> </persistence-unit-defaults> </persistence-unit-metadata> . . . </entity-mappings>
persistence.xml
<persistence ... > <persistence-unit name="foo"> <mapping-file>orm.xml</mapping-file> </persistence-unit> </persistence>
对于EclipseLink,可以配置一个SessionCustomizerclass
public class FooSessionCustomizer implements org.eclipse.persistence.config.SessionCustomizer { @Override public void customize(Session session) throws Exception { session.getLogin().setTableQualifier("Sankofa"); } }
persistence.xml
<persistence ... > <persistence-unit name="foo"> <properties> <property name="eclipselink.session.customizer" value="foo.customizer.FooSessionCustomizer" /> </properties> </persistence-unit> </persistence>
@Table 注释有一个“schema”元素,用于在实体级别配置模式
@Table(name = "Users", schema = "Sankofa")