TomEE 找不到我配置的数据源

TomEE cannot find my configured data source

我正在尝试在 Tom EE 中配置非 JTA 数据源。我在我的 WEB-INF 目录中创建了一个 resource.xml 文件,在我的 META-INF 目录中创建了一个 persistence.xml 文件。问题似乎是 Tom EE 未获取 resource.xml 文件中配置的数据源。请协助。

这是我遇到的异常;

EL Severe]: ejb: 2022-02-18 14:27:58.423--ServerSession(726371619)--Exception [EclipseLink-7060] (Eclipse Persistence Services - 3.0.2.v202107160933): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Cannot acquire data source [dashboardDS].
Internal Exception: javax.naming.NameNotFoundException: Name [dashboardDS] is not bound in this Context. Unable to find [dashboardDS].
Feb 18, 2022 2:27:58 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [faces] in context with path [/dashboard] threw exception [jakarta.el.ELException: Error reading [towers] on type [za.co.ezimax.dashboard.Map$$OwbNormalScopeProxy0]] with root cause
javax.naming.NameNotFoundException: Name [dashboardDS] is not bound in this Context. Unable to find [dashboardDS].
    at org.apache.naming.NamingContext.lookup(NamingContext.java:833)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:160)
    at org.apache.naming.SelectorContext.lookup(SelectorContext.java:140)
    at java.naming/javax.naming.InitialContext.lookup(InitialContext.java:413)
    at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:120)
    at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:172)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.setOrDetectDatasource(DatabaseSessionImpl.java:225)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:807)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:261)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:771)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:222)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:330)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:350)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)
    at za.co.ezimax.dashboard.Database.<init>(Database.java:20)
    at za.co.ezimax.dashboard.Database.<clinit>(Database.java:13)
    at za.co.ezimax.dashboard.Map.<init>(Map.java:15)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at org.apache.webbeans.inject.InjectableConstructor.doInjection(InjectableConstructor.java:72)
    at org.apache.webbeans.portable.InjectionTargetImpl.newInstance(InjectionTargetImpl.java:201)
    at org.apache.webbeans.portable.InjectionTargetImpl.produce(InjectionTargetImpl.java:184)
    at org.apache.webbeans.portable.AbstractProducer.produce(AbstractProducer.java:134)
    at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:124)
    at org.apache.webbeans.component.ManagedBean.create(ManagedBean.java:66)
    at org.apache.webbeans.context.creational.BeanInstanceBag.create(BeanInstanceBag.java:76)
    at org.apache.webbeans.context.AbstractContext.getInstance(AbstractContext.java:159)
    at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:125)
    at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:101)
    at org.apache.webbeans.intercept.RequestScopedBeanInterceptorHandler.getContextualInstance(RequestScopedBeanInterceptorHandler.java:76)
    at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.get(NormalScopedBeanInterceptorHandler.java:71)
    at za.co.ezimax.dashboard.Map$$OwbNormalScopeProxy0.getTowers(za/co/ezimax/dashboard/Map.java)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at jakarta.el.BeanELResolver.getValue(BeanELResolver.java:88)
    at jakarta.el.CompositeELResolver.getValue(CompositeELResolver.java:62)
    at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:179)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190)
    at org.apache.webbeans.el22.WrappedValueExpression.getValue(WrappedValueExpression.java:68)
    at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getValue(ContextAwareTagValueExpression.java:93)
    at jakarta.faces.component._DeltaStateHelper.eval(_DeltaStateHelper.java:357)
    at org.apache.myfaces.view.facelets.component.UIRepeat.getValue(UIRepeat.java:303)
    at org.apache.myfaces.view.facelets.component.UIRepeat.createDataModel(UIRepeat.java:226)
    at org.apache.myfaces.view.facelets.component.UIRepeat.getDataModel(UIRepeat.java:218)
    at org.apache.myfaces.view.facelets.component.UIRepeat._validateAttributes(UIRepeat.java:892)
    at org.apache.myfaces.view.facelets.component.UIRepeat.process(UIRepeat.java:1022)
    at org.apache.myfaces.view.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:1816)
    at jakarta.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:545)
    at jakarta.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:554)
    at jakarta.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:554)
    at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1897)
    at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:315)
    at jakarta.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
    at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:122)
    at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:266)
    at jakarta.faces.webapp.FacesServlet.service(FacesServlet.java:206)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
    at org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:67)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:353)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:870)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1696)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:833)

这是我的 persitence.xml 文件。

<?xml version="1.0" encoding="UTF-8"?>
<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_0.xsd"
    version="3.0">
    <persistence-unit name="dashboard" transaction-type="RESOURCE_LOCAL">
        <non-jta-data-source>dashboardDS</non-jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
    </persistence-unit>
</persistence>

这是我的 resource.xml 文件,位于 WEB-INF 目录中:

<?xml version="1.0" encoding="UTF-8"?>
<Resources>
    <Resource id="dashboardDS" type="javax.sql.DataSource">
        jdbcDriver com.mysql.cj.jdbc.Driver
        jdbcUrl jdbc:mysql://localhost:3306/dashboard
        password ******
        userName root
        jtaManaged false
    </Resource>
</Resources>

根据JSR 338 Java Persistence API 2.2

In Java EE environments, the jta-data-source and non-jta-data-source elements are used to specify the JNDI name of the JTA and/or non-JTA data source to be used by the persistence provider. If neither is specified, the deployer must specify a JTA data source at deployment or the default JTA data source must be provided by the container, and a JTA EntityManagerFactory will be created to correspond to it.

因此,您需要在 persistence.xml 中通过其 JNDI 名称指定数据源。

资源(在 TomEE 中)默认在 java:openejb/Resource/<id> 下注册。

因此,您需要将non-jta-data-source标签调整为:

 <non-jta-data-source>java:openejb/Resource/dashboardDS</non-jta-data-source>