尝试在 Helidon MicroProfile 项目中使用 EntityManager 时遇到 NullPointerException。发生异常是因为当我尝试创建查询时 EntityManager 为空。错误信息是:
java.lang.NullPointerException: Cannot invoke "jakarta.persistence.EntityManager.createQuery(String, java.lang.Class)" because "this.entityManager" is null
这发生在我的 DataBaseService 类的 getDataBaseData() 方法中。我正在使用 @PersistenceContext 注解来注入 EntityManager,但注入似乎没有按预期工作。
我正在使用Helidon MP,并且我已经为Derby配置了persistence.xml作为数据库。
这里是资源/META-INF/beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
version="4.0"
bean-discovery-mode="annotated">
</beans>
资源/META-INF/persistence.xml:
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
https://jakarta.ee/xml/ns/persistence/persistence_3_1.xsd"
version="3.1">
<persistence-unit name="explanationsDbPU" transaction-type="JTA">
<description> explanation database persistence unit </description>
<jta-data-source>explanationsDS</jta-data-source>
<class>fr.uge.xplain.Explanation</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
资源/application.yaml:
javax:
sql:
DataSource:
explanationsDS:
driver: org.apache.derby.jdbc.EmbeddedDataSource
url: jdbc:derby:memory:explanations;create=true
user: admin
password: admin
解释(实体):
package fr.uge.xplain;
import jakarta.persistence.*;
import java.time.LocalDate;
@Entity
public class Explanation {
@Id
@GeneratedValue(strategy = GenerationType.AUTO) // Option pour une meilleure compatibilité
private int id;
@Column(name = "source_code", length = 255)
private String sourceCode;
@Column(name = "explanations", length = 255)
private String explanations;
@Column(name = "creation_date")
private LocalDate creationDate;
// Getters
public int getId() {
return id;
}
public String getSourceCode() {
return sourceCode;
}
public String getExplanations() {
return explanations;
}
public LocalDate getCreationDate() {
return creationDate;
}
// Setters
public void setSourceCode(String sourceCode) {
this.sourceCode = sourceCode;
}
public void setId(int id) {
this.id = id;
}
public void setExplanations(String explanations) {
this.explanations = explanations;
}
public void setCreationDate(LocalDate creationDate) {
this.creationDate = creationDate;
}
}
DataBaseService.java:
package fr.uge.xplain;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import java.util.List;
@ApplicationScoped
public class DataBaseService {
@PersistenceContext(unitName = "explanationsDbPU")
private EntityManager entityManager;
public List<Explanation> getDataBaseData() {
return entityManager.createQuery("SELECT e FROM Explanation e ORDER BY e.creationDate DESC", Explanation.class)
.getResultList();
}
@Transactional
public void setDataBaseData(Explanation explanation) {
entityManager.persist(explanation);
}
}
DataBaseResource(前端的 POST 和 GET):
package fr.uge.xplain;
import jakarta.inject.Inject;
import jakarta.persistence.PersistenceContext;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
@Path("/database")
public class DataBaseResource {
@Inject
private DataBaseService dataBaseService;
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getDatabaseData() {
List<Explanation> data = dataBaseService.getDataBaseData();
if (data.isEmpty()) {
return Response.status(Response.Status.NOT_FOUND)
.entity(Map.of("message", "No data found"))
.build();
}
return Response.ok(data).build();
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response addData(Explanation explanation) {
dataBaseService.setDataBaseData(explanation);
return Response.status(Response.Status.CREATED).build();
}
}
更新:我只是忘记包含 JPA 依赖项!
<dependency>
<groupId>io.helidon.integrations.cdi</groupId>
<artifactId>helidon-integrations-cdi-jpa</artifactId>
</dependency>