Helidon MP EntityManager 始终返回 NULL

问题描述 投票:0回答:1

尝试在 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();
    }
}
  • @PersistenceContext 注解是否使用错误?
  • 如何确保 EntityManager 正确注入到 Helidon MicroProfile 项目中?
  • 是否需要任何其他配置才能使 EntityManager 与 CDI 和 Helidon 配合使用?
java xml cdi helidon
1个回答
0
投票

更新:我只是忘记包含 JPA 依赖项!

<dependency>
     <groupId>io.helidon.integrations.cdi</groupId>
     <artifactId>helidon-integrations-cdi-jpa</artifactId>
</dependency>
© www.soinside.com 2019 - 2024. All rights reserved.